Clang Project

clang_source_code/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
5struct 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
13struct null_t {
14  operator int*();
15};
16
17namespace 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
69using X::A;
70
71void f();
72void f(int);
73
74void 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
202template<typename T, typename U>
203void 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
210template void h<A, int>(A);
211template void h<A(&)[4], A &>(A(&)[4]);
212template void h<A(&)[13], A>(A(&)[13]);
213template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
214
215template<typename T>
216void 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}
223template void i<A[13]>(A*); // expected-note {{requested here}}
224template void i<const A>(const A); // expected-note {{requested here}}
225
226struct StdBeginEnd {};
227namespace std {
228  int *begin(StdBeginEnd);
229  int *end(StdBeginEnd);
230}
231void DR1442() {
232  for (auto a : StdBeginEnd()) {} // expected-error {{invalid range expression of type 'StdBeginEnd'; no viable 'begin'}}
233}
234
235namespace 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}
242int *begin(NS::NoADL);
243int *end(NS::NoADL);
244
245struct VoidBeginADL {};
246void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}
247void end(VoidBeginADL);
248
249void 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
259void example() {
260  int array[5] = { 1, 2, 3, 4, 5 };
261  for (int &x : array)
262    x *= 2;
263}
264
265namespace 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
275namespace 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}
329