diff options
Diffstat (limited to 'test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp')
-rw-r--r-- | test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp | 104 |
1 files changed, 65 insertions, 39 deletions
diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index 96bb47212274..3952afdeff11 100644 --- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -3,20 +3,24 @@ struct pr12960 { int begin; void foo(int x) { - for (int& it : x) { // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type 'int'}} + for (int& it : x) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}} } } }; -namespace std { +struct null_t { + operator int*(); +}; + +namespace X { template<typename T> - auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 4{{ignored: substitution failure}} + auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 2{{ignored: substitution failure}} template<typename T> auto end(T &&t) -> decltype(t.end()) { return t.end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} template<typename T> auto begin(T &&t) -> decltype(t.alt_begin()) { return t.alt_begin(); } // expected-note {{selected 'begin' template [with T = }} \ - expected-note 4{{candidate template ignored: substitution failure [with T = }} + expected-note 2{{candidate template ignored: substitution failure [with T = }} template<typename T> auto end(T &&t) -> decltype(t.alt_end()) { return t.alt_end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} @@ -27,19 +31,28 @@ namespace std { } using namespace inner; -} -struct A { // expected-note 2 {{candidate constructor}} - A(); - int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}} - int *end(); -}; + struct A { // expected-note 2 {{candidate constructor}} + A(); + int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}} + int *end(); + }; -struct B { - B(); - int *alt_begin(); - int *alt_end(); -}; + struct B { + B(); + int *alt_begin(); + int *alt_end(); + }; + + struct NoBeginADL { + null_t alt_end(); + }; + struct NoEndADL { + null_t alt_begin(); + }; +} + +using X::A; void f(); void f(int); @@ -49,19 +62,19 @@ void g() { A __begin; for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} } - for (char *a : B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} + for (char *a : X::B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} } // FIXME: Terrible diagnostic here. auto deduction should fail, but does not! for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}} } for (auto a : A()) { } - for (auto a : B()) { + for (auto a : X::B()) { } for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}} } // : is not a typo for :: here. - for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'A'}} + for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'X::A'}} } for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}} } @@ -92,9 +105,6 @@ void g() { for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}} ; - struct null_t { - operator int*(); - }; struct Differ { int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}} null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}} @@ -110,15 +120,9 @@ void g() { for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}} for (constexpr int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'constexpr'}} - struct NoBeginADL { - null_t alt_end(); - }; - struct NoEndADL { - null_t alt_begin(); - }; - for (auto u : NoBeginADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type 'NoBeginADL'}} + for (auto u : X::NoBeginADL()) { // expected-error {{invalid range expression of type 'X::NoBeginADL'; no viable 'begin' function available}} } - for (auto u : NoEndADL()) { // expected-error {{no matching function for call to 'end'}} expected-note {{range has type 'NoEndADL'}} + for (auto u : X::NoEndADL()) { // expected-error {{invalid range expression of type 'X::NoEndADL'; no viable 'end' function available}} } struct NoBegin { @@ -129,14 +133,15 @@ void g() { }; for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}} } - for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} + for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} } struct NoIncr { void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}} void *end(); }; - for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}} + for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}}\ + expected-note {{in implicit call to 'operator++' for iterator of type 'NoIncr'}} } struct NoNotEq { @@ -144,7 +149,19 @@ void g() { NoNotEq end(); void operator++(); }; - for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}} + for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}\ + expected-note {{in implicit call to 'operator!=' for iterator of type 'NoNotEq'}} + } + + struct NoDeref { + NoDeref begin(); // expected-note {{selected 'begin' function}} + NoDeref end(); + void operator++(); + bool operator!=(NoDeref &); + }; + + for (auto u : NoDeref()) { // expected-error {{indirection requires pointer operand}} \ + expected-note {{in implicit call to 'operator*' for iterator of type 'NoDeref'}} } struct NoCopy { @@ -156,8 +173,7 @@ void g() { for (int n : NoCopy()) { // ok } - for (int n : 42) { // expected-error {{no matching function for call to 'begin'}} \ - expected-note {{range has type 'int'}} + for (int n : 42) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}} } for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}} @@ -166,7 +182,7 @@ void g() { template<typename T, typename U> void h(T t) { - for (U u : t) { // expected-error {{no viable conversion from 'A' to 'int'}} + for (U u : t) { // expected-error {{no viable conversion from 'X::A' to 'int'}} } for (auto u : t) { } @@ -179,14 +195,24 @@ template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}} template<typename T> void i(T t) { - for (auto u : t) { // expected-error {{no matching function for call to 'begin'}} \ + for (auto u : t) { // expected-error {{invalid range expression of type 'X::A *'; no viable 'begin' function available}} \ expected-error {{member function 'begin' not viable}} \ - expected-note {{range has type}} + expected-note {{when looking up 'begin' function}} + } } template void i<A[13]>(A*); // expected-note {{requested here}} template void i<const A>(const A); // expected-note {{requested here}} +struct StdBeginEnd {}; +namespace std { + int *begin(StdBeginEnd); + int *end(StdBeginEnd); +} +void DR1442() { + for (auto a : StdBeginEnd()) {} // expected-error {{invalid range expression of type 'StdBeginEnd'; no viable 'begin'}} +} + namespace NS { class ADL {}; int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}} @@ -204,9 +230,10 @@ void end(VoidBeginADL); void j() { for (auto u : NS::ADL()) { } - for (auto u : NS::NoADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}} + for (auto u : NS::NoADL()) { // expected-error {{invalid range expression of type 'NS::NoADL'; no viable 'begin' function available}} } for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}} + } } @@ -215,4 +242,3 @@ void example() { for (int &x : array) x *= 2; } - |