p1.cpp revision b1502bcd67fb593a95cbf73ec3814f4015666da0
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
11struct null_t {
12  operator int*();
13};
14
15namespace 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
55using X::A;
56
57void f();
58void f(int);
59
60void 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'}}
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
183template<typename T, typename U>
184void 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
191template void h<A, int>(A);
192template void h<A(&)[4], A &>(A(&)[4]);
193template void h<A(&)[13], A>(A(&)[13]);
194template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
195
196template<typename T>
197void 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}
204template void i<A[13]>(A*); // expected-note {{requested here}}
205template void i<const A>(const A); // expected-note {{requested here}}
206
207struct StdBeginEnd {};
208namespace std {
209  int *begin(StdBeginEnd);
210  int *end(StdBeginEnd);
211}
212void DR1442() {
213  for (auto a : StdBeginEnd()) {} // expected-error {{invalid range expression of type 'StdBeginEnd'; no viable 'begin'}}
214}
215
216namespace 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}
223int *begin(NS::NoADL);
224int *end(NS::NoADL);
225
226struct VoidBeginADL {};
227void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}
228void end(VoidBeginADL);
229
230void 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
240void example() {
241  int array[5] = { 1, 2, 3, 4, 5 };
242  for (int &x : array)
243    x *= 2;
244}
245