blob: a45b35f715928aa434f03b6479aa1c64680806a1 [file] [log] [blame]
Richard Smith762bb9d2011-10-13 22:29:44 +00001// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
Richard Smithad762fc2011-04-14 22:09:26 +00002
3namespace std {
4 template<typename T>
5 auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 4{{ignored: substitution failure}}
6 template<typename T>
7 auto end(T &&t) -> decltype(t.end()) { return t.end(); } // expected-note {{candidate template ignored: substitution failure [with T = }}
8
9 template<typename T>
10 auto begin(T &&t) -> decltype(t.alt_begin()) { return t.alt_begin(); } // expected-note {{selected 'begin' template [with T = }} \
11 expected-note 4{{candidate template ignored: substitution failure [with T = }}
12 template<typename T>
13 auto end(T &&t) -> decltype(t.alt_end()) { return t.alt_end(); } // expected-note {{candidate template ignored: substitution failure [with T = }}
14
15 namespace inner {
16 // These should never be considered.
17 int begin(int);
18 int end(int);
19 }
20
21 using namespace inner;
22}
23
Sebastian Redl85ea7aa2011-08-30 19:58:05 +000024struct A { // expected-note 2 {{candidate constructor}}
Richard Smithad762fc2011-04-14 22:09:26 +000025 A();
26 int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}}
27 int *end();
28};
29
30struct B {
31 B();
32 int *alt_begin();
33 int *alt_end();
34};
35
Douglas Gregor9625e442011-05-21 22:16:50 +000036void f();
37void f(int);
Richard Smithad762fc2011-04-14 22:09:26 +000038
39void g() {
40 for (int a : A())
41 A __begin;
42 for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
43 }
44 for (char *a : B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}
45 }
46 // FIXME: Terrible diagnostic here. auto deduction should fail, but does not!
Douglas Gregor9625e442011-05-21 22:16:50 +000047 for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}}
Richard Smithad762fc2011-04-14 22:09:26 +000048 }
49 for (auto a : A()) {
50 }
51 for (auto a : B()) {
52 }
53 for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}}
54 }
55 // : is not a typo for :: here.
56 for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'A'}}
57 }
58 for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}}
59 }
60
61 for (auto a : A())
62 for (auto b : A()) {
63 __range.begin(); // expected-error {{use of undeclared identifier '__range'}}
64 ++__begin; // expected-error {{use of undeclared identifier '__begin'}}
65 --__end; // expected-error {{use of undeclared identifier '__end'}}
66 }
67
68 for (char c : "test")
69 ;
70 for (auto a : f()) // expected-error {{cannot use type 'void' as a range}}
71 ;
72
73 extern int incomplete[];
74 for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}}
75 ;
76 extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}}
77 for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}}
78 ;
79
80 struct VoidBegin {
81 void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}}
82 void end();
83 };
84 for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}}
85 ;
86
87 struct null_t {
88 operator int*();
89 };
90 struct Differ {
91 int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}}
92 null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}}
93 };
94 for (auto a : Differ()) // expected-error {{'begin' and 'end' must return the same type (got 'int *' and 'null_t')}}
95 ;
96
97 for (void f() : "error") // expected-error {{for range declaration must declare a variable}}
98 ;
99
100 for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}}
101 for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}}
102 for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}}
Richard Smithc6d990a2011-09-29 19:11:37 +0000103 for (constexpr int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'constexpr'}}
Richard Smithad762fc2011-04-14 22:09:26 +0000104
105 struct NoBeginADL {
106 null_t alt_end();
107 };
108 struct NoEndADL {
109 null_t alt_begin();
110 };
111 for (auto u : NoBeginADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type 'NoBeginADL'}}
112 }
113 for (auto u : NoEndADL()) { // expected-error {{no matching function for call to 'end'}} expected-note {{range has type 'NoEndADL'}}
114 }
115
116 struct NoBegin {
117 null_t end();
118 };
119 struct NoEnd {
120 null_t begin();
121 };
122 for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}}
123 }
124 for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}}
125 }
126
127 struct NoIncr {
128 void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}}
129 void *end();
130 };
Richard Trieu2fe9b7f2011-12-15 00:38:15 +0000131 for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}}
Richard Smithad762fc2011-04-14 22:09:26 +0000132 }
133
134 struct NoNotEq {
135 NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}}
136 NoNotEq end();
137 void operator++();
138 };
139 for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}
140 }
141
142 struct NoCopy {
143 NoCopy();
144 NoCopy(const NoCopy &) = delete;
145 int *begin();
146 int *end();
147 };
148 for (int n : NoCopy()) { // ok
149 }
150
151 for (int n : 42) { // expected-error {{no matching function for call to 'begin'}} \
152 expected-note {{range has type 'int'}}
153 }
154
155 for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}}
156 }
157}
158
159template<typename T, typename U>
160void h(T t) {
161 for (U u : t) { // expected-error {{no viable conversion from 'A' to 'int'}}
162 }
163 for (auto u : t) {
164 }
165}
166
167template void h<A, int>(A);
168template void h<A(&)[4], A &>(A(&)[4]);
169template void h<A(&)[13], A>(A(&)[13]);
170template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
171
172template<typename T>
173void i(T t) {
174 for (auto u : t) { // expected-error {{no matching function for call to 'begin'}} \
175 expected-error {{member function 'begin' not viable}} \
176 expected-note {{range has type}}
177 }
178}
179template void i<A[13]>(A*); // expected-note {{requested here}}
180template void i<const A>(const A); // expected-note {{requested here}}
181
182namespace NS {
183 class ADL {};
184 int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}}
185 int *end(ADL);
186
187 class NoADL {};
188}
189int *begin(NS::NoADL);
190int *end(NS::NoADL);
191
192struct VoidBeginADL {};
193void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}
194void end(VoidBeginADL);
195
196void j() {
197 for (auto u : NS::ADL()) {
198 }
199 for (auto u : NS::NoADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}}
200 }
201 for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}}
202 }
203}
204
205void example() {
206 int array[5] = { 1, 2, 3, 4, 5 };
207 for (int &x : array)
208 x *= 2;
209}