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'}} expected-warning {{deprecated}} 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 } 245 246 namespace rdar13712739 { 247 template<typename T> 248 void foo(const T& t) { 249 auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}} 250 for (auto &blah : x) { } 251 } 252 253 template void foo(const int&); // expected-note{{in instantiation of function template specialization}} 254 } 255