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