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++1z -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 {{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++1z 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 {{range type 'NoBegin' has 'end' member but no 'begin' member}} 154 } 155 for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} 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 {{member function 'begin' not viable}} \ 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