]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
[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
3 struct pr12960 {
4   int begin;
5   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>
17     auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 2{{ignored: substitution failure}}
18   template<typename 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>
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>
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
55 using X::A;
56
57 void f();
58 void f(int);
59
60 void g() {
61   for (int a : A())
62     A __begin;
63   for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
64   }
65   for (char *a : X::B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
66   }
67   // FIXME: Terrible diagnostic here. auto deduction should fail, but does not!
68   for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}}
69   }
70   for (auto a : A()) {
71   }
72   for (auto a : X::B()) {
73   }
74   for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}}
75   }
76   // : is not a typo for :: here.
77   for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'X::A'}}
78   }
79   for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}}
80   }
81
82   for (auto a : A())
83     for (auto b : A()) {
84       __range.begin(); // expected-error {{use of undeclared identifier '__range'}}
85       ++__begin; // expected-error {{use of undeclared identifier '__begin'}}
86       --__end; // expected-error {{use of undeclared identifier '__end'}}
87     }
88
89   for (char c : "test")
90     ;
91   for (auto a : f()) // expected-error {{cannot use type 'void' as a range}}
92     ;
93
94   extern int incomplete[];
95   for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}}
96     ;
97   extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}}
98   for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}}
99     ;
100
101   struct VoidBegin {
102     void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}}
103     void end();
104   };
105   for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}}
106     ;
107
108   struct Differ {
109     int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}}
110     null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}}
111   };
112   for (auto a : Differ()) // expected-error {{'begin' and 'end' must return the same type (got 'int *' and 'null_t')}}
113     ;
114
115   for (void f() : "error") // expected-error {{for range declaration must declare a variable}}
116     ;
117
118   for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}}
119   for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}}
120   for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}}
121   for (constexpr int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'constexpr'}}
122
123   for (auto u : X::NoBeginADL()) { // expected-error {{invalid range expression of type 'X::NoBeginADL'; no viable 'begin' function available}}
124   }
125   for (auto u : X::NoEndADL()) { // expected-error {{invalid range expression of type 'X::NoEndADL'; no viable 'end' function available}}
126   }
127
128   struct NoBegin {
129     null_t end();
130   };
131   struct NoEnd {
132     null_t begin();
133   };
134   for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}}
135   }
136   for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} 
137   }
138
139   struct NoIncr {
140     void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}}
141     void *end();
142   };
143   for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}}\
144     expected-note {{in implicit call to 'operator++' for iterator of type 'NoIncr'}}
145   }
146
147   struct NoNotEq {
148     NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}}
149     NoNotEq end();
150     void operator++();
151   };
152   for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}\
153     expected-note {{in implicit call to 'operator!=' for iterator of type 'NoNotEq'}}
154   }
155
156   struct NoDeref {
157     NoDeref begin(); // expected-note {{selected 'begin' function}}
158     NoDeref end();
159     void operator++();
160     bool operator!=(NoDeref &);
161   };
162
163   for (auto u : NoDeref()) { // expected-error {{indirection requires pointer operand}} \
164     expected-note {{in implicit call to 'operator*' for iterator of type 'NoDeref'}}
165   }
166
167   struct NoCopy {
168     NoCopy();
169     NoCopy(const NoCopy &) = delete;
170     int *begin();
171     int *end();
172   };
173   for (int n : NoCopy()) { // ok
174   }
175
176   for (int n : 42) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
177   }
178
179   for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}}
180   }
181 }
182
183 template<typename T, typename U>
184 void h(T t) {
185   for (U u : t) { // expected-error {{no viable conversion from 'X::A' to 'int'}}
186   }
187   for (auto u : t) {
188   }
189 }
190
191 template void h<A, int>(A);
192 template void h<A(&)[4], A &>(A(&)[4]);
193 template void h<A(&)[13], A>(A(&)[13]);
194 template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
195
196 template<typename T>
197 void i(T t) {
198   for (auto u : t) { // expected-error {{invalid range expression of type 'X::A *'; no viable 'begin' function available}} \
199                         expected-error {{member function 'begin' not viable}} \
200                         expected-note {{when looking up 'begin' function}}
201
202   }
203 }
204 template void i<A[13]>(A*); // expected-note {{requested here}}
205 template void i<const A>(const A); // expected-note {{requested here}}
206
207 struct StdBeginEnd {};
208 namespace std {
209   int *begin(StdBeginEnd);
210   int *end(StdBeginEnd);
211 }
212 void DR1442() {
213   for (auto a : StdBeginEnd()) {} // expected-error {{invalid range expression of type 'StdBeginEnd'; no viable 'begin'}}
214 }
215
216 namespace NS {
217   class ADL {};
218   int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}}
219   int *end(ADL);
220
221   class NoADL {};
222 }
223 int *begin(NS::NoADL);
224 int *end(NS::NoADL);
225
226 struct VoidBeginADL {};
227 void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}
228 void end(VoidBeginADL);
229
230 void j() {
231   for (auto u : NS::ADL()) {
232   }
233   for (auto u : NS::NoADL()) { // expected-error {{invalid range expression of type 'NS::NoADL'; no viable 'begin' function available}}
234   }
235   for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}}
236
237   }
238 }
239
240 void example() {
241   int array[5] = { 1, 2, 3, 4, 5 };
242   for (int &x : array)
243     x *= 2;
244 }