1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 
3 struct pr12960 {
4   int begin;
foopr129605   void foo(int x) {
6     for (int& it : x) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
7     }
8   }
9 };
10 
11 struct null_t {
12   operator int*();
13 };
14 
15 namespace X {
16   template<typename T>
begin(T && t)17     auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 2{{ignored: substitution failure}}
18   template<typename T>
end(T && t)19     auto end(T &&t) -> decltype(t.end()) { return t.end(); } // expected-note {{candidate template ignored: substitution failure [with T = }}
20 
21   template<typename T>
begin(T && t)22     auto begin(T &&t) -> decltype(t.alt_begin()) { return t.alt_begin(); } // expected-note {{selected 'begin' template [with T = }} \
23                                                                               expected-note 2{{candidate template ignored: substitution failure [with T = }}
24   template<typename T>
end(T && t)25     auto end(T &&t) -> decltype(t.alt_end()) { return t.alt_end(); } // expected-note {{candidate template ignored: substitution failure [with T = }}
26 
27   namespace inner {
28     // These should never be considered.
29     int begin(int);
30     int end(int);
31   }
32 
33   using namespace inner;
34 
35   struct A { // expected-note 2 {{candidate constructor}}
36     A();
37     int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}}
38     int *end();
39   };
40 
41   struct B {
42     B();
43     int *alt_begin();
44     int *alt_end();
45   };
46 
47   struct NoBeginADL {
48     null_t alt_end();
49   };
50   struct NoEndADL {
51     null_t alt_begin();
52   };
53 
54   struct C {
55     C();
56     struct It {
57       int val;
operator int&X::C::It58       operator int &() { return val; }
59     };
60     It begin();
61     It end();
62   };
63 
operator *(const C::It &)64   constexpr int operator*(const C::It &) { return 0; }
65 }
66 
67 using X::A;
68 
69 void f();
70 void f(int);
71 
g()72 void g() {
73   for (int a : A())
74     A __begin;
75   for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
76   }
77   for (char *a : X::B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
78   }
79   // FIXME: Terrible diagnostic here. auto deduction should fail, but does not!
80   for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}}
81   }
82   for (auto a : A()) {
83   }
84   for (auto a : X::B()) {
85   }
86   for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}}
87   }
88   // : is not a typo for :: here.
89   for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'X::A'}}
90   }
91   for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}}
92   }
93 
94   for (auto a : A())
95     for (auto b : A()) {
96       __range.begin(); // expected-error {{use of undeclared identifier '__range'}}
97       ++__begin; // expected-error {{use of undeclared identifier '__begin'}}
98       --__end; // expected-error {{use of undeclared identifier '__end'}}
99     }
100 
101   for (char c : "test")
102     ;
103   for (auto a : f()) // expected-error {{cannot use type 'void' as a range}}
104     ;
105 
106   extern int incomplete[];
107   for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}}
108     ;
109   extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}}
110   for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}}
111     ;
112 
113   struct VoidBegin {
114     void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}}
115     void end();
116   };
117   for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}}
118     ;
119 
120   struct Differ {
121     int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}}
122     null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}}
123   };
124   for (auto a : Differ()) // expected-error {{'begin' and 'end' must return the same type (got 'int *' and 'null_t')}}
125     ;
126 
127   for (void f() : "error") // expected-error {{for range declaration must declare a variable}}
128     ;
129 
130   for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}}
131   for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}}
132   for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}} expected-warning {{deprecated}}
133   for (constexpr int a : X::C()) {} // OK per CWG issue #1204.
134 
135   for (auto u : X::NoBeginADL()) { // expected-error {{invalid range expression of type 'X::NoBeginADL'; no viable 'begin' function available}}
136   }
137   for (auto u : X::NoEndADL()) { // expected-error {{invalid range expression of type 'X::NoEndADL'; no viable 'end' function available}}
138   }
139 
140   struct NoBegin {
141     null_t end();
142   };
143   struct NoEnd {
144     null_t begin();
145   };
146   for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}}
147   }
148   for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}}
149   }
150 
151   struct NoIncr {
152     void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}}
153     void *end();
154   };
155   for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}}\
156     expected-note {{in implicit call to 'operator++' for iterator of type 'NoIncr'}}
157   }
158 
159   struct NoNotEq {
160     NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}}
161     NoNotEq end();
162     void operator++();
163   };
164   for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}\
165     expected-note {{in implicit call to 'operator!=' for iterator of type 'NoNotEq'}}
166   }
167 
168   struct NoDeref {
169     NoDeref begin(); // expected-note {{selected 'begin' function}}
170     NoDeref end();
171     void operator++();
172     bool operator!=(NoDeref &);
173   };
174 
175   for (auto u : NoDeref()) { // expected-error {{indirection requires pointer operand}} \
176     expected-note {{in implicit call to 'operator*' for iterator of type 'NoDeref'}}
177   }
178 
179   struct NoCopy {
180     NoCopy();
181     NoCopy(const NoCopy &) = delete;
182     int *begin();
183     int *end();
184   };
185   for (int n : NoCopy()) { // ok
186   }
187 
188   for (int n : 42) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
189   }
190 
191   for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}}
192   }
193 }
194 
195 template<typename T, typename U>
h(T t)196 void h(T t) {
197   for (U u : t) { // expected-error {{no viable conversion from 'X::A' to 'int'}}
198   }
199   for (auto u : t) {
200   }
201 }
202 
203 template void h<A, int>(A);
204 template void h<A(&)[4], A &>(A(&)[4]);
205 template void h<A(&)[13], A>(A(&)[13]);
206 template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
207 
208 template<typename T>
i(T t)209 void i(T t) {
210   for (auto u : t) { // expected-error {{invalid range expression of type 'X::A *'; no viable 'begin' function available}} \
211                         expected-error {{member function 'begin' not viable}} \
212                         expected-note {{when looking up 'begin' function}}
213 
214   }
215 }
216 template void i<A[13]>(A*); // expected-note {{requested here}}
217 template void i<const A>(const A); // expected-note {{requested here}}
218 
219 struct StdBeginEnd {};
220 namespace std {
221   int *begin(StdBeginEnd);
222   int *end(StdBeginEnd);
223 }
DR1442()224 void DR1442() {
225   for (auto a : StdBeginEnd()) {} // expected-error {{invalid range expression of type 'StdBeginEnd'; no viable 'begin'}}
226 }
227 
228 namespace NS {
229   class ADL {};
230   int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}}
231   int *end(ADL);
232 
233   class NoADL {};
234 }
235 int *begin(NS::NoADL);
236 int *end(NS::NoADL);
237 
238 struct VoidBeginADL {};
239 void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}
240 void end(VoidBeginADL);
241 
j()242 void j() {
243   for (auto u : NS::ADL()) {
244   }
245   for (auto u : NS::NoADL()) { // expected-error {{invalid range expression of type 'NS::NoADL'; no viable 'begin' function available}}
246   }
247   for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}}
248 
249   }
250 }
251 
example()252 void example() {
253   int array[5] = { 1, 2, 3, 4, 5 };
254   for (int &x : array)
255     x *= 2;
256 }
257 
258 namespace rdar13712739 {
259   template<typename T>
foo(const T & t)260   void foo(const T& t) {
261     auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}}
262     for (auto &blah : x) { }
263   }
264 
265   template void foo(const int&); // expected-note{{in instantiation of function template specialization}}
266 }
267