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