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