345 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s2// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s3// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s4 5struct 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 13struct null_t {14 operator int*();15};16 17namespace 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 struct D {69 D();70 using Ty = int[2];71 Ty *begin();72 Ty *end();73 };74 75 void test_D() {76#if __cplusplus >= 201703L77 for (extern auto [x, y] : D()) {78 } // expected-error@-1 {{structured binding declaration cannot be declared 'extern'}}79 // expected-error@-2 {{loop variable '[x, y]' may not be declared 'extern'}}80#endif81 }82}83 84using X::A;85 86void f();87void f(int);88 89void g() {90 for (int a : A())91 A __begin;92 for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}93 }94 for (char *a : X::B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}}95 }96 // FIXME: Terrible diagnostic here. auto deduction should fail, but does not!97 for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}}98 }99 for (auto a : A()) {100 }101 for (auto a : X::B()) {102 }103 for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}}104 }105 // : is not a typo for :: here.106 for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'A'}}107 }108 for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}}109 }110 111 for (auto a : A())112 for (auto b : A()) {113 __range.begin(); // expected-error {{use of undeclared identifier '__range'}}114 ++__begin; // expected-error {{use of undeclared identifier '__begin'}}115 --__end; // expected-error {{use of undeclared identifier '__end'}}116 }117 118 for (char c : "test")119 ;120 for (auto a : f()) // expected-error {{cannot use type 'void' as a range}}121 ;122 123 extern int incomplete[];124 for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int[]' as a range}}125 ;126 extern struct Incomplete also_incomplete[2]; // expected-note 2{{forward declaration}}127 for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete[2]' as a range}}128 ;129 130 struct VoidBegin {131 void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}}132 void end();133 };134 for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}}135 ;136 137 struct Differ {138 int *begin();139 null_t end();140 };141 for (auto a : Differ())142#if __cplusplus <= 201402L143 // expected-warning@-2 {{'begin' and 'end' returning different types ('int *' and 'null_t') is a C++17 extension}}144 // expected-note@-6 {{selected 'begin' function with iterator type 'int *'}}145 // expected-note@-6 {{selected 'end' function with iterator type 'null_t'}}146#endif147 ;148 149 for (void f() : "error") // expected-error {{for range declaration must declare a variable}}150 ;151 152 for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}}153 for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}}154 for (thread_local int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'thread_local'}}155 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}}156 for (constexpr int a : X::C()) {} // OK per CWG issue #1204.157 158 for (auto u : X::NoBeginADL()) { // expected-error {{invalid range expression of type 'X::NoBeginADL'; no viable 'begin' function available}}159 }160 for (auto u : X::NoEndADL()) { // expected-error {{invalid range expression of type 'X::NoEndADL'; no viable 'end' function available}}161 }162 163 struct NoBegin {164 null_t end();165 };166 struct NoEnd {167 null_t begin();168 };169 for (auto u : NoBegin()) { // expected-error {{no viable 'begin' function available}}170 }171 for (auto u : NoEnd()) { // expected-error {{no viable 'end' function available}}172 }173 174 struct NoIncr {175 void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}}176 void *end();177 };178 for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}}\179 expected-note {{in implicit call to 'operator++' for iterator of type 'NoIncr'}}180 }181 182 struct NoNotEq {183 NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}}184 NoNotEq end();185 void operator++();186 };187 for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}\188 expected-note {{in implicit call to 'operator!=' for iterator of type 'NoNotEq'}}189 }190 191 struct NoDeref {192 NoDeref begin(); // expected-note {{selected 'begin' function}}193 NoDeref end();194 void operator++();195 bool operator!=(NoDeref &);196 };197 198 for (auto u : NoDeref()) { // expected-error {{indirection requires pointer operand}} \199 expected-note {{in implicit call to 'operator*' for iterator of type 'NoDeref'}}200 }201 202 struct NoCopy {203 NoCopy();204 NoCopy(const NoCopy &) = delete;205 int *begin();206 int *end();207 };208 for (int n : NoCopy()) { // ok209 }210 211 for (int n : 42) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}212 }213 214 for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}}215 }216}217 218template<typename T, typename U>219void h(T t) {220 for (U u : t) { // expected-error {{no viable conversion from 'X::A' to 'int'}}221 }222 for (auto u : t) {223 }224}225 226template void h<A, int>(A);227template void h<A(&)[4], A &>(A(&)[4]);228template void h<A(&)[13], A>(A(&)[13]);229template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}230 231template<typename T>232void i(T t) {233 for (auto u : t) { // expected-error {{invalid range expression of type 'X::A *'; no viable 'begin' function available}} \234 expected-error {{'this' argument to member function 'begin' has type 'const X::A', but function is not marked const}} \235 expected-note {{when looking up 'begin' function}}236 237 }238}239template void i<A[13]>(A*); // expected-note {{requested here}}240template void i<const A>(const A); // expected-note {{requested here}}241 242struct StdBeginEnd {};243namespace std {244 int *begin(StdBeginEnd);245 int *end(StdBeginEnd);246}247void DR1442() {248 for (auto a : StdBeginEnd()) {} // expected-error {{invalid range expression of type 'StdBeginEnd'; no viable 'begin'}}249}250 251namespace NS {252 class ADL {};253 int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'ADL'}}254 int *end(ADL);255 256 class NoADL {};257}258int *begin(NS::NoADL);259int *end(NS::NoADL);260 261struct VoidBeginADL {};262void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}263void end(VoidBeginADL);264 265void j() {266 for (auto u : NS::ADL()) {267 }268 for (auto u : NS::NoADL()) { // expected-error {{invalid range expression of type 'NS::NoADL'; no viable 'begin' function available}}269 }270 for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}}271 272 }273}274 275void example() {276 int array[5] = { 1, 2, 3, 4, 5 };277 for (int &x : array)278 x *= 2;279}280 281namespace rdar13712739 {282 template<typename T>283 void foo(const T& t) {284 auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}}285 for (auto &blah : x) { }286 }287 288 template void foo(const int&); // expected-note{{in instantiation of function template specialization}}289}290 291namespace p0962r1 {292 namespace NA {293 struct A {294 void begin();295 };296 int *begin(A);297 int *end(A);298 }299 300 namespace NB {301 struct B {302 void end();303 };304 int *begin(B);305 int *end(B);306 }307 308 namespace NC {309 struct C {310 void begin();311 };312 int *begin(C);313 }314 315 namespace ND {316 struct D {317 void end();318 };319 int *end(D);320 }321 322 namespace NE {323 struct E {324 void begin(); // expected-note {{member is not a candidate because range type 'NE::E' has no 'end' member}}325 };326 int *end(E);327 }328 329 namespace NF {330 struct F {331 void end(); // expected-note {{member is not a candidate because range type 'NF::F' has no 'begin' member}}332 };333 int *begin(F);334 }335 336 void use(NA::A a, NB::B b, NC::C c, ND::D d, NE::E e, NF::F f) {337 for (auto x : a) {}338 for (auto x : b) {}339 for (auto x : c) {} // expected-error {{invalid range expression of type 'NC::C'; no viable 'end' function available}}340 for (auto x : d) {} // expected-error {{invalid range expression of type 'ND::D'; no viable 'begin' function available}}341 for (auto x : e) {} // expected-error {{invalid range expression of type 'NE::E'; no viable 'begin' function available}}342 for (auto x : f) {} // expected-error {{invalid range expression of type 'NF::F'; no viable 'end' function available}}343 }344}345