blob: c06bf0102bcfead12199b0071ed35fa0cc70d515 [file] [log] [blame]
Aaron Ballmanf25731a2015-02-16 23:12:37 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
Timm Bäder5bb9c082024-06-09 14:58:21 +02002// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -fexperimental-new-constant-interpreter
Richard Smith02e85f32011-04-14 22:09:26 +00003
4namespace value_range_detail {
5 template<typename T>
6 class value_range_iter {
7 T t;
8 public:
9 value_range_iter(const T &t) : t(t) {}
10 T operator*() const { return t; }
11 bool operator!=(const value_range_iter &o) const { return t != o.t; }
12 value_range_iter &operator++() { ++t; return *this; }
13 };
14
15 template<typename T>
16 struct value_range {
17 value_range(const T &a, const T &b) : begin_(a), end_(b) {}
18 value_range_iter<T> begin_, end_;
19 };
20
21 template<typename T>
22 value_range_iter<T> begin(const value_range<T> &r) { return r.begin_; }
23 template<typename T>
24 value_range_iter<T> end(const value_range<T> &r) { return r.end_; }
25
26
27 struct end_t {};
28
29 template<typename T>
30 class value_range_step_iter {
31 T it, step;
32 public:
33 value_range_step_iter(const T &it, const T &step) : it(it), step(step) {}
34 T operator*() const { return it; }
35 bool operator!=(value_range_step_iter end) const { return it != end.it; }
36 value_range_step_iter &operator++() { it += step; return *this; }
37 };
38
39 template<typename T>
40 class value_range_step {
41 T it, step, end_;
42 public:
43 value_range_step(const T &it, const T &end, const T &step) :
44 it(it), end_(end), step(step) {}
45 typedef value_range_step_iter<T> iterator;
46 iterator begin() const { return iterator(it, step); }
47 iterator end() const { return iterator(end_, step); }
48 };
49}
50
51template<typename T>
52value_range_detail::value_range<T> range(const T &a, const T &b) { return value_range_detail::value_range<T>(a, b); }
53
54template<typename T>
55value_range_detail::value_range_step<T> range(const T &a, const T &b, const T &step) { return value_range_detail::value_range_step<T>(a, b, step); }
56
57
58namespace map_range {
59 template<typename T>
60 class vector {
61 T storage[100];
62 decltype(sizeof(char)) size;
63 public:
64 vector() : size() {}
65 void push_back(T t) { storage[size++] = t; }
66 T *begin() { return storage; }
67 T *end() { return storage + size; }
68 };
69
70 template<typename T> struct tuple_elem {
71 T t;
72 tuple_elem() {}
73 tuple_elem(T t) : t(t) {}
74 };
75 template<typename... A>
76 struct tuple : tuple_elem<A>... {
77 tuple() : tuple_elem<A>()... {}
78 tuple(A... a) : tuple_elem<A>(a)... {}
79 template<typename B> B &get() { return tuple_elem<B>::t; }
80 };
81
82 template<typename F, typename I>
83 class map_iter {
84 F f;
85 I i;
86 public:
87 map_iter(F f, I i) : f(f), i(i) {}
88 auto operator*() const -> decltype(f(*i)) { return f(*i); }
89 bool operator!=(const map_iter &o) const { return i != o.i; }
90 map_iter &operator++() { ++i; return *this; }
91 };
92
93 template<typename T>
94 struct iter_pair {
95 T begin_, end_;
96 iter_pair(T begin, T end) : begin_(begin), end_(end) {}
97 };
98 template<typename T> T begin(iter_pair<T> p) { return p.begin_; }
99 template<typename T> T end(iter_pair<T> p) { return p.end_; }
100
101 template<typename...> class mem_fun_impl;
102 template<typename R, typename T, typename... A>
103 class mem_fun_impl<R (T::*)(A...)> {
104 typedef R (T::*F)(A...);
105 F f;
106 public:
107 mem_fun_impl(F f) : f(f) {}
108 R operator()(T &t, A &&...a) const { return (t.*f)(static_cast<A&&>(a)...); }
109 };
110 template<typename F> mem_fun_impl<F> mem_fun(F f) { return mem_fun_impl<F>(f); }
111
112 template<typename F, typename T>
113 auto map(const F &f, T &t) -> iter_pair<map_iter<F, decltype(t.begin())>> {
114 typedef map_iter<F, decltype(t.begin())> iter;
115 return iter_pair<iter>(iter(f, t.begin()), iter(f, t.end()));
116 }
117}
118
Fariborz Jahanianeed5e322012-09-19 16:20:17 +0000119#define assert(b) if (!(b)) { return 1; }
Richard Smith02e85f32011-04-14 22:09:26 +0000120int main() {
121 int total = 0;
122
123 for (auto n : range(1, 5)) {
124 total += n;
125 }
Fariborz Jahanianeed5e322012-09-19 16:20:17 +0000126 assert(total == 10);
Richard Smith02e85f32011-04-14 22:09:26 +0000127
128 for (auto n : range(10, 100, 10)) {
129 total += n;
130 }
Fariborz Jahanianeed5e322012-09-19 16:20:17 +0000131 assert(total == 460);
Richard Smith02e85f32011-04-14 22:09:26 +0000132
133 map_range::vector<char> chars;
134 chars.push_back('a');
135 chars.push_back('b');
136 chars.push_back('c');
137 for (char c : chars) {
138 ++total;
139 }
Fariborz Jahanianeed5e322012-09-19 16:20:17 +0000140 assert(total == 463);
Richard Smith02e85f32011-04-14 22:09:26 +0000141
142 typedef map_range::tuple<int, double> T;
143 map_range::vector<T> pairs;
144 pairs.push_back(T(42, 12.9));
145 pairs.push_back(T(6, 4.2));
146 pairs.push_back(T(9, 1.1));
147 for (auto a : map(map_range::mem_fun(&T::get<int>), pairs)) {
148 total += a;
149 }
Fariborz Jahanianeed5e322012-09-19 16:20:17 +0000150 assert(total == 500);
Richard Smith02e85f32011-04-14 22:09:26 +0000151}
John McCallcf6e0c82012-01-27 01:29:43 +0000152
153// PR11793
154namespace test2 {
155 class A {
156 int xs[10]; // expected-note {{implicitly declared private here}}
157 };
158 void test(A &a) {
159 for (int x : a.xs) { } // expected-error {{'xs' is a private member of 'test2::A'}}
160 }
161}
Eli Friedman87d32802012-01-31 22:45:40 +0000162
163namespace test3 {
164 // Make sure this doesn't crash
165 struct A {};
166 struct B { ~B(); operator bool(); };
167 struct C { B operator!=(const C&); C& operator++(); int operator*(); };
168 C begin(const A&);
169 C end(const A&);
170 template<typename T> void f() { for (auto a : A()) {} }
171 void g() { f<int>(); }
172}
Richard Smith9a2b7e82012-02-21 20:01:35 +0000173
174namespace test4 {
175 void f() {
176 int y;
177
178 // Make sure these don't crash. Better diagnostics would be nice.
179 for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
Richard Smith03a4aa32016-06-23 19:02:52 +0000180 for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}}
Richard Smith955bf012014-06-19 11:42:00 +0000181 for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
Richard Smith03a4aa32016-06-23 19:02:52 +0000182 for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}}
Richard Smith9a2b7e82012-02-21 20:01:35 +0000183 }
184}
Richard Smith3249fed2013-08-21 01:40:36 +0000185
186namespace test5 {
187 // Test error-recovery.
188 void f() {
189 for (auto x : undeclared_identifier) // expected-error {{undeclared identifier}}
190 for (auto y : x->foo)
191 y->bar();
192 for (auto x : 123) // expected-error {{no viable 'begin'}}
193 x->foo();
194 }
195}
Richard Trieu08254692013-10-11 22:16:04 +0000196
197namespace test6 {
198 void foo(int arr[]) { // expected-note {{declared here}}
199 for (auto i : arr) { }
David Blaikieaee49252021-10-14 14:52:47 -0700200 // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int[]' is treated as pointer type 'int *'}}
Richard Trieu08254692013-10-11 22:16:04 +0000201 }
202
203 struct vector {
204 int *begin() { return 0; }
205 int *end() { return 0; }
206 };
207
208 void foo(vector arr[]) { // expected-note {{declared here}}
209 // Don't suggest to dereference arr.
210 for (auto i : arr) { }
Matheus Izvekov15f3cd62021-10-11 18:15:36 +0200211 // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'vector[]' is treated as pointer type 'vector *'}}
Richard Trieu08254692013-10-11 22:16:04 +0000212 }
213}
Richard Smith955bf012014-06-19 11:42:00 +0000214
215namespace test7 {
216 void f() {
217 int arr[5], b;
Richard Smith83d3f152014-11-27 01:54:27 +0000218 for (a : arr) {} // expected-error {{requires type for loop variable}}
219 // FIXME: Give a different error in this case?
220 for (b : arr) {} // expected-error {{requires type for loop variable}}
221 for (arr : arr) {} // expected-error {{requires type for loop variable}}
222 for (c alignas(8) : arr) { // expected-error {{requires type for loop variable}}
Richard Smith955bf012014-06-19 11:42:00 +0000223 static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
224 }
Richard Smith5412b212018-05-16 01:08:07 +0000225 for (d alignas(1) : arr) {} // expected-error {{requested alignment is less than minimum}} expected-error {{requires type for loop variable}}
Richard Smith4f902c72016-03-08 00:32:55 +0000226 for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}}
Richard Smith955bf012014-06-19 11:42:00 +0000227 }
228}
Serge Pavlov458ea762014-07-16 05:16:52 +0000229
230namespace pr18587 {
231 class Arg {};
232 struct Cont {
233 int *begin();
234 int *end();
235 };
236 void AddAllArgs(Cont &x) {
237 for (auto Arg: x) {
238 }
239 }
240}
Faisal Vali1ca2d962017-05-15 01:49:19 +0000241
242namespace PR32933 {
243// https://bugs.llvm.org/show_bug.cgi?id=32933
244void foo ()
Aaron Ballman84a3aad2023-10-20 13:08:50 -0400245{
246 int b = 1, a[b]; // expected-warning {{variable length arrays in C++ are a Clang extension}} \
247 expected-note {{read of non-const variable 'b' is not allowed in a constant expression}} \
248 expected-note {{declared here}}
Faisal Vali1ca2d962017-05-15 01:49:19 +0000249 a[0] = 0;
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +0000250 [&] { for (int c : a) 0; } (); // expected-warning {{expression result unused}}
Faisal Vali1ca2d962017-05-15 01:49:19 +0000251}
252
253
Aaron Ballman84a3aad2023-10-20 13:08:50 -0400254int foo(int b) { // expected-note {{declared here}}
255 int varr[b][(b+=8)]; // expected-warning 2{{variable length arrays in C++ are a Clang extension}} \
256 expected-note {{function parameter 'b' with unknown value cannot be used in a constant expression}}
257 b = 15;
Faisal Vali1ca2d962017-05-15 01:49:19 +0000258 [&] {
259 int i = 0;
Aaron Ballman84a3aad2023-10-20 13:08:50 -0400260 for (auto &c : varr)
Faisal Vali1ca2d962017-05-15 01:49:19 +0000261 {
262 c[0] = ++b;
263 }
264 [&] {
265 int i = 0;
266 for (auto &c : varr) {
267 int j = 0;
268 for(auto &c2 : c) {
269 ++j;
270 }
271 ++i;
272 }
273 }();
274 }();
275 return b;
276}
Richard Smithd699da42018-05-14 20:15:04 +0000277}