p1.cpp revision 85ea7aa961deac1d754f610af8062ae3f8b4e2a5
1// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
2
3namespace 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
24struct A { // expected-note 2 {{candidate constructor}}
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
30struct B {
31  B();
32  int *alt_begin();
33  int *alt_end();
34};
35
36void f();
37void f(int);
38
39void 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!
47  for (double a : f) { // expected-error {{cannot use type '<overloaded function type>' as a range}}
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'}}
103  // FIXME: when clang supports constexpr, this should be rejected.
104  for (constexpr int a : A()) {} // desired-error {{loop variable 'a' may not be declared 'constexpr'}}
105
106  struct NoBeginADL {
107    null_t alt_end();
108  };
109  struct NoEndADL {
110    null_t alt_begin();
111  };
112  for (auto u : NoBeginADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type 'NoBeginADL'}}
113  }
114  for (auto u : NoEndADL()) { // expected-error {{no matching function for call to 'end'}} expected-note {{range has type 'NoEndADL'}}
115  }
116
117  struct NoBegin {
118    null_t end();
119  };
120  struct NoEnd {
121    null_t begin();
122  };
123  for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}}
124  }
125  for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}}
126  }
127
128  struct NoIncr {
129    void *begin(); // expected-note {{selected 'begin' function with iterator type 'void *'}}
130    void *end();
131  };
132  for (auto u : NoIncr()) { // expected-error {{arithmetic on a pointer to void type}}
133  }
134
135  struct NoNotEq {
136    NoNotEq begin(); // expected-note {{selected 'begin' function with iterator type 'NoNotEq'}}
137    NoNotEq end();
138    void operator++();
139  };
140  for (auto u : NoNotEq()) { // expected-error {{invalid operands to binary expression}}
141  }
142
143  struct NoCopy {
144    NoCopy();
145    NoCopy(const NoCopy &) = delete;
146    int *begin();
147    int *end();
148  };
149  for (int n : NoCopy()) { // ok
150  }
151
152  for (int n : 42) { // expected-error {{no matching function for call to 'begin'}} \
153                        expected-note {{range has type 'int'}}
154  }
155
156  for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}}
157  }
158}
159
160template<typename T, typename U>
161void h(T t) {
162  for (U u : t) { // expected-error {{no viable conversion from 'A' to 'int'}}
163  }
164  for (auto u : t) {
165  }
166}
167
168template void h<A, int>(A);
169template void h<A(&)[4], A &>(A(&)[4]);
170template void h<A(&)[13], A>(A(&)[13]);
171template void h<A(&)[13], int>(A(&)[13]); // expected-note {{requested here}}
172
173template<typename T>
174void i(T t) {
175  for (auto u : t) { // expected-error {{no matching function for call to 'begin'}} \
176                        expected-error {{member function 'begin' not viable}} \
177                        expected-note {{range has type}}
178  }
179}
180template void i<A[13]>(A*); // expected-note {{requested here}}
181template void i<const A>(const A); // expected-note {{requested here}}
182
183namespace NS {
184  class ADL {};
185  int *begin(ADL); // expected-note {{no known conversion from 'NS::NoADL' to 'NS::ADL'}}
186  int *end(ADL);
187
188  class NoADL {};
189}
190int *begin(NS::NoADL);
191int *end(NS::NoADL);
192
193struct VoidBeginADL {};
194void begin(VoidBeginADL); // expected-note {{selected 'begin' function with iterator type 'void'}}
195void end(VoidBeginADL);
196
197void j() {
198  for (auto u : NS::ADL()) {
199  }
200  for (auto u : NS::NoADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}}
201  }
202  for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}}
203  }
204}
205
206void example() {
207  int array[5] = { 1, 2, 3, 4, 5 };
208  for (int &x : array)
209    x *= 2;
210}
211