Richard Smith | 762bb9d | 2011-10-13 22:29:44 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 2 | |
| 3 | namespace std { |
| 4 | template<typename T> |
| 5 | auto begin(T &&t) -> decltype(t.begin()) { return t.begin(); } // expected-note 4{{ignored: substitution failure}} |
| 6 | template<typename T> |
| 7 | auto end(T &&t) -> decltype(t.end()) { return t.end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} |
| 8 | |
| 9 | template<typename T> |
| 10 | auto begin(T &&t) -> decltype(t.alt_begin()) { return t.alt_begin(); } // expected-note {{selected 'begin' template [with T = }} \ |
| 11 | expected-note 4{{candidate template ignored: substitution failure [with T = }} |
| 12 | template<typename T> |
| 13 | auto end(T &&t) -> decltype(t.alt_end()) { return t.alt_end(); } // expected-note {{candidate template ignored: substitution failure [with T = }} |
| 14 | |
| 15 | namespace inner { |
| 16 | // These should never be considered. |
| 17 | int begin(int); |
| 18 | int end(int); |
| 19 | } |
| 20 | |
| 21 | using namespace inner; |
| 22 | } |
| 23 | |
Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 24 | struct A { // expected-note 2 {{candidate constructor}} |
Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 25 | A(); |
| 26 | int *begin(); // expected-note 3{{selected 'begin' function with iterator type 'int *'}} expected-note {{'begin' declared here}} |
| 27 | int *end(); |
| 28 | }; |
| 29 | |
| 30 | struct B { |
| 31 | B(); |
| 32 | int *alt_begin(); |
| 33 | int *alt_end(); |
| 34 | }; |
| 35 | |
Douglas Gregor | 9625e44 | 2011-05-21 22:16:50 +0000 | [diff] [blame] | 36 | void f(); |
| 37 | void f(int); |
Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 38 | |
| 39 | void g() { |
| 40 | for (int a : A()) |
| 41 | A __begin; |
| 42 | for (char *a : A()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} |
| 43 | } |
| 44 | for (char *a : B()) { // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'int'}} |
| 45 | } |
| 46 | // FIXME: Terrible diagnostic here. auto deduction should fail, but does not! |
Douglas Gregor | 9625e44 | 2011-05-21 22:16:50 +0000 | [diff] [blame] | 47 | for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}} |
Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 48 | } |
| 49 | for (auto a : A()) { |
| 50 | } |
| 51 | for (auto a : B()) { |
| 52 | } |
| 53 | for (auto *a : A()) { // expected-error {{variable 'a' with type 'auto *' has incompatible initializer of type 'int'}} |
| 54 | } |
| 55 | // : is not a typo for :: here. |
| 56 | for (A NS:A()) { // expected-error {{no viable conversion from 'int' to 'A'}} |
| 57 | } |
| 58 | for (auto not_in_scope : not_in_scope) { // expected-error {{use of undeclared identifier 'not_in_scope'}} |
| 59 | } |
| 60 | |
| 61 | for (auto a : A()) |
| 62 | for (auto b : A()) { |
| 63 | __range.begin(); // expected-error {{use of undeclared identifier '__range'}} |
| 64 | ++__begin; // expected-error {{use of undeclared identifier '__begin'}} |
| 65 | --__end; // expected-error {{use of undeclared identifier '__end'}} |
| 66 | } |
| 67 | |
| 68 | for (char c : "test") |
| 69 | ; |
| 70 | for (auto a : f()) // expected-error {{cannot use type 'void' as a range}} |
| 71 | ; |
| 72 | |
| 73 | extern int incomplete[]; |
| 74 | for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}} |
| 75 | ; |
| 76 | extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}} |
| 77 | for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}} |
| 78 | ; |
| 79 | |
| 80 | struct VoidBegin { |
| 81 | void begin(); // expected-note {{selected 'begin' function with iterator type 'void'}} |
| 82 | void end(); |
| 83 | }; |
| 84 | for (auto a : VoidBegin()) // expected-error {{cannot use type 'void' as an iterator}} |
| 85 | ; |
| 86 | |
| 87 | struct null_t { |
| 88 | operator int*(); |
| 89 | }; |
| 90 | struct Differ { |
| 91 | int *begin(); // expected-note {{selected 'begin' function with iterator type 'int *'}} |
| 92 | null_t end(); // expected-note {{selected 'end' function with iterator type 'null_t'}} |
| 93 | }; |
| 94 | for (auto a : Differ()) // expected-error {{'begin' and 'end' must return the same type (got 'int *' and 'null_t')}} |
| 95 | ; |
| 96 | |
| 97 | for (void f() : "error") // expected-error {{for range declaration must declare a variable}} |
| 98 | ; |
| 99 | |
| 100 | for (extern int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'extern'}} |
| 101 | for (static int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'static'}} |
| 102 | for (register int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'register'}} |
Richard Smith | c6d990a | 2011-09-29 19:11:37 +0000 | [diff] [blame] | 103 | for (constexpr int a : A()) {} // expected-error {{loop variable 'a' may not be declared 'constexpr'}} |
Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 104 | |
| 105 | struct NoBeginADL { |
| 106 | null_t alt_end(); |
| 107 | }; |
| 108 | struct NoEndADL { |
| 109 | null_t alt_begin(); |
| 110 | }; |
| 111 | for (auto u : NoBeginADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type 'NoBeginADL'}} |
| 112 | } |
| 113 | for (auto u : NoEndADL()) { // expected-error {{no matching function for call to 'end'}} expected-note {{range has type 'NoEndADL'}} |
| 114 | } |
| 115 | |
| 116 | struct NoBegin { |
| 117 | null_t end(); |
| 118 | }; |
| 119 | struct NoEnd { |
| 120 | null_t begin(); |
| 121 | }; |
| 122 | for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}} |
| 123 | } |
| 124 | for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}} |
| 125 | } |
| 126 | |
| 127 | struct NoIncr { |
| 128 | void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}} |
| 129 | void *end(); |
| 130 | }; |
Richard Trieu | 2fe9b7f | 2011-12-15 00:38:15 +0000 | [diff] [blame] | 131 | for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void}} |
Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | struct NoNotEq { |
| 135 | NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}} |
| 136 | NoNotEq end(); |
| 137 | void operator++(); |
| 138 | }; |
| 139 | for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}} |
| 140 | } |
| 141 | |
| 142 | struct NoCopy { |
| 143 | NoCopy(); |
| 144 | NoCopy(const NoCopy &) = delete; |
| 145 | int *begin(); |
| 146 | int *end(); |
| 147 | }; |
| 148 | for (int n : NoCopy()) { // ok |
| 149 | } |
| 150 | |
| 151 | for (int n : 42) { // expected-error {{no matching function for call to 'begin'}} \ |
| 152 | expected-note {{range has type 'int'}} |
| 153 | } |
| 154 | |
| 155 | for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}} |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | template<typename T, typename U> |
| 160 | void h(T t) { |
| 161 | for (U u : t) { // expected-error {{no viable conversion from 'A' to 'int'}} |
| 162 | } |
| 163 | for (auto u : t) { |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | template void h<A, int>(A); |
| 168 | template void h<A(&)[4], A &>(A(&)[4]); |
| 169 | template void h<A(&)[13], A>(A(&)[13]); |
| 170 | template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}} |
| 171 | |
| 172 | template<typename T> |
| 173 | void i(T t) { |
| 174 | for (auto u : t) { // expected-error {{no matching function for call to 'begin'}} \ |
| 175 | expected-error {{member function 'begin' not viable}} \ |
| 176 | expected-note {{range has type}} |
| 177 | } |
| 178 | } |
| 179 | template void i<A[13]>(A*); // expected-note {{requested here}} |
| 180 | template void i<const A>(const A); // expected-note {{requested here}} |
| 181 | |
| 182 | namespace NS { |
| 183 | class ADL {}; |
| 184 | int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}} |
| 185 | int *end(ADL); |
| 186 | |
| 187 | class NoADL {}; |
| 188 | } |
| 189 | int *begin(NS::NoADL); |
| 190 | int *end(NS::NoADL); |
| 191 | |
| 192 | struct VoidBeginADL {}; |
| 193 | void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}} |
| 194 | void end(VoidBeginADL); |
| 195 | |
| 196 | void j() { |
| 197 | for (auto u : NS::ADL()) { |
| 198 | } |
| 199 | for (auto u : NS::NoADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}} |
| 200 | } |
| 201 | for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}} |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | void example() { |
| 206 | int array[5] = { 1, 2, 3, 4, 5 }; |
| 207 | for (int &x : array) |
| 208 | x *= 2; |
| 209 | } |