]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / test / CXX / stmt.stmt / stmt.iter / stmt.ranged / p1.cpp
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++17 -fsyntax-only -verify %s
4
5 struct pr12960 {
6   int begin;
7   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>
19     auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 2{{ignored: substitution failure}}
20   template<typename 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>
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>
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;
60       operator int &() { return val; }
61     };
62     It begin();
63     It end();
64   };
65
66   constexpr int operator*(const C::It &) { return 0; }
67 }
68
69 using X::A;
70
71 void f();
72 void f(int);
73
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 2{{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++17 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 {{no viable 'begin' function available}}
154   }
155   for (auto u : NoEnd()) { // expected-error {{no viable 'end' function available}}
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>
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>
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 {{'this' argument to member function 'begin' has type 'const X::A', but function is not marked const}} \
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 }
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
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
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>
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
275 namespace p0962r1 {
276   namespace NA {
277     struct A {
278       void begin();
279     };
280     int *begin(A);
281     int *end(A);
282   }
283
284   namespace NB {
285     struct B {
286       void end();
287     };
288     int *begin(B);
289     int *end(B);
290   }
291
292   namespace NC {
293     struct C {
294       void begin();
295     };
296     int *begin(C);
297   }
298
299   namespace ND {
300     struct D {
301       void end();
302     };
303     int *end(D);
304   }
305
306   namespace NE {
307     struct E {
308       void begin(); // expected-note {{member is not a candidate because range type 'p0962r1::NE::E' has no 'end' member}}
309     };
310     int *end(E);
311   }
312
313   namespace NF {
314     struct F {
315       void end(); // expected-note {{member is not a candidate because range type 'p0962r1::NF::F' has no 'begin' member}}
316     };
317     int *begin(F);
318   }
319
320   void use(NA::A a, NB::B b, NC::C c, ND::D d, NE::E e, NF::F f) {
321     for (auto x : a) {}
322     for (auto x : b) {}
323     for (auto x : c) {} // expected-error {{no viable 'end' function}}
324     for (auto x : d) {} // expected-error {{no viable 'begin' function}}
325     for (auto x : e) {} // expected-error {{no viable 'begin' function}}
326     for (auto x : f) {} // expected-error {{no viable 'end' function}}
327   }
328 }