1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 2 3struct 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 11namespace std { 12 template<typename T> 13 auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 4{{ignored: substitution failure}} 14 template<typename 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> 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> 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 32struct 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 38struct B { 39 B(); 40 int *alt_begin(); 41 int *alt_end(); 42}; 43 44void f(); 45void f(int); 46 47void 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 179template<typename T, typename U> 180void 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 187template void h<A, int>(A); 188template void h<A(&)[4], A &>(A(&)[4]); 189template void h<A(&)[13], A>(A(&)[13]); 190template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}} 191 192template<typename T> 193void 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} 200template void i<A[13]>(A*); // expected-note {{requested here}} 201template void i<const A>(const A); // expected-note {{requested here}} 202 203namespace 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} 210int *begin(NS::NoADL); 211int *end(NS::NoADL); 212 213struct VoidBeginADL {}; 214void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}} 215void end(VoidBeginADL); 216 217void 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 227void example() { 228 int array[5] = { 1, 2, 3, 4, 5 }; 229 for (int &x : array) 230 x *= 2; 231} 232