1 | // RUN: %clang_cc1 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion |
2 | |
3 | namespace StaticAssertFoldTest { |
4 | |
5 | int x; |
6 | static_assert(++x, "test"); // expected-error {{not an integral constant expression}} |
7 | static_assert(false, "test"); // expected-error {{test}} |
8 | |
9 | } |
10 | |
11 | typedef decltype(sizeof(char)) size_t; |
12 | |
13 | template<typename T> constexpr T id(const T &t) { return t; } |
14 | template<typename T> constexpr T min(const T &a, const T &b) { |
15 | return a < b ? a : b; |
16 | } |
17 | template<typename T> constexpr T max(const T &a, const T &b) { |
18 | return a < b ? b : a; |
19 | } |
20 | template<typename T, size_t N> constexpr T *begin(T (&xs)[N]) { return xs; } |
21 | template<typename T, size_t N> constexpr T *end(T (&xs)[N]) { return xs + N; } |
22 | |
23 | struct MemberZero { |
24 | constexpr int zero() const { return 0; } |
25 | }; |
26 | |
27 | namespace DerivedToVBaseCast { |
28 | |
29 | struct U { int n; }; |
30 | struct V : U { int n; }; |
31 | struct A : virtual V { int n; }; |
32 | struct Aa { int n; }; |
33 | struct B : virtual A, Aa {}; |
34 | struct C : virtual A, Aa {}; |
35 | struct D : B, C {}; |
36 | |
37 | D d; |
38 | constexpr B *p = &d; |
39 | constexpr C *q = &d; |
40 | |
41 | static_assert((void*)p != (void*)q, ""); |
42 | static_assert((A*)p == (A*)q, ""); |
43 | static_assert((Aa*)p != (Aa*)q, ""); |
44 | |
45 | constexpr B &pp = d; |
46 | constexpr C &qq = d; |
47 | static_assert((void*)&pp != (void*)&qq, ""); |
48 | static_assert(&(A&)pp == &(A&)qq, ""); |
49 | static_assert(&(Aa&)pp != &(Aa&)qq, ""); |
50 | |
51 | constexpr V *v = p; |
52 | constexpr V *w = q; |
53 | constexpr V *x = (A*)p; |
54 | static_assert(v == w, ""); |
55 | static_assert(v == x, ""); |
56 | |
57 | static_assert((U*)&d == p, ""); |
58 | static_assert((U*)&d == q, ""); |
59 | static_assert((U*)&d == v, ""); |
60 | static_assert((U*)&d == w, ""); |
61 | static_assert((U*)&d == x, ""); |
62 | |
63 | struct X {}; |
64 | struct Y1 : virtual X {}; |
65 | struct Y2 : X {}; |
66 | struct Z : Y1, Y2 {}; |
67 | Z z; |
68 | static_assert((X*)(Y1*)&z != (X*)(Y2*)&z, ""); |
69 | } |
70 | |
71 | namespace ConstCast { |
72 | |
73 | constexpr int n1 = 0; |
74 | constexpr int n2 = const_cast<int&>(n1); |
75 | constexpr int *n3 = const_cast<int*>(&n1); |
76 | constexpr int n4 = *const_cast<int*>(&n1); |
77 | constexpr const int * const *n5 = const_cast<const int* const*>(&n3); |
78 | constexpr int **n6 = const_cast<int**>(&n3); |
79 | constexpr int n7 = **n5; |
80 | constexpr int n8 = **n6; |
81 | |
82 | // const_cast from prvalue to xvalue. |
83 | struct A { int n; }; |
84 | constexpr int n9 = (const_cast<A&&>(A{123})).n; |
85 | static_assert(n9 == 123, ""); |
86 | |
87 | } |
88 | |
89 | namespace TemplateArgumentConversion { |
90 | template<int n> struct IntParam {}; |
91 | |
92 | using IntParam0 = IntParam<0>; |
93 | using IntParam0 = IntParam<id(0)>; |
94 | using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}} |
95 | } |
96 | |
97 | namespace CaseStatements { |
98 | int x; |
99 | void f(int n) { |
100 | switch (n) { |
101 | case MemberZero().zero: // expected-error {{did you mean to call it with no arguments?}} expected-note {{previous}} |
102 | case id(0): // expected-error {{duplicate case value '0'}} |
103 | return; |
104 | case __builtin_constant_p(true) ? (__SIZE_TYPE__)&x : 0:; // expected-error {{constant}} |
105 | } |
106 | } |
107 | } |
108 | |
109 | extern int &Recurse1; |
110 | int &Recurse2 = Recurse1; // expected-note {{declared here}} |
111 | int &Recurse1 = Recurse2; |
112 | constexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'Recurse2' is not a constant expression}} |
113 | |
114 | extern const int RecurseA; |
115 | const int RecurseB = RecurseA; // expected-note {{declared here}} |
116 | const int RecurseA = 10; |
117 | constexpr int RecurseC = RecurseB; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'RecurseB' is not a constant expression}} |
118 | |
119 | namespace MemberEnum { |
120 | struct WithMemberEnum { |
121 | enum E { A = 42 }; |
122 | } wme; |
123 | |
124 | static_assert(wme.A == 42, ""); |
125 | } |
126 | |
127 | namespace DefaultArguments { |
128 | |
129 | const int z = int(); |
130 | constexpr int Sum(int a = 0, const int &b = 0, const int *c = &z, char d = 0) { |
131 | return a + b + *c + d; |
132 | } |
133 | const int four = 4; |
134 | constexpr int eight = 8; |
135 | constexpr const int twentyseven = 27; |
136 | static_assert(Sum() == 0, ""); |
137 | static_assert(Sum(1) == 1, ""); |
138 | static_assert(Sum(1, four) == 5, ""); |
139 | static_assert(Sum(1, eight, &twentyseven) == 36, ""); |
140 | static_assert(Sum(1, 2, &four, eight) == 15, ""); |
141 | |
142 | } |
143 | |
144 | namespace Ellipsis { |
145 | |
146 | // Note, values passed through an ellipsis can't actually be used. |
147 | constexpr int F(int a, ...) { return a; } |
148 | static_assert(F(0) == 0, ""); |
149 | static_assert(F(1, 0) == 1, ""); |
150 | static_assert(F(2, "test") == 2, ""); |
151 | static_assert(F(3, &F) == 3, ""); |
152 | int k = 0; // expected-note {{here}} |
153 | static_assert(F(4, k) == 3, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'k'}} |
154 | |
155 | } |
156 | |
157 | namespace Recursion { |
158 | constexpr int fib(int n) { return n > 1 ? fib(n-1) + fib(n-2) : n; } |
159 | static_assert(fib(11) == 89, ""); |
160 | |
161 | constexpr int gcd_inner(int a, int b) { |
162 | return b == 0 ? a : gcd_inner(b, a % b); |
163 | } |
164 | constexpr int gcd(int a, int b) { |
165 | return gcd_inner(max(a, b), min(a, b)); |
166 | } |
167 | |
168 | static_assert(gcd(1749237, 5628959) == 7, ""); |
169 | } |
170 | |
171 | namespace FunctionCast { |
172 | // When folding, we allow functions to be cast to different types. Such |
173 | // cast functions cannot be called, even if they're constexpr. |
174 | constexpr int f() { return 1; } |
175 | typedef double (*DoubleFn)(); |
176 | typedef int (*IntFn)(); |
177 | int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}} expected-warning{{C99 feature}} |
178 | int b[(int)IntFn(f)()]; // ok |
179 | } |
180 | |
181 | namespace StaticMemberFunction { |
182 | struct S { |
183 | static constexpr int k = 42; |
184 | static constexpr int f(int n) { return n * k + 2; } |
185 | } s; |
186 | |
187 | constexpr int n = s.f(19); |
188 | static_assert(S::f(19) == 800, ""); |
189 | static_assert(s.f(19) == 800, ""); |
190 | static_assert(n == 800, ""); |
191 | |
192 | constexpr int (*sf1)(int) = &S::f; |
193 | constexpr int (*sf2)(int) = &s.f; |
194 | constexpr const int *sk = &s.k; |
195 | } |
196 | |
197 | namespace ParameterScopes { |
198 | |
199 | const int k = 42; |
200 | constexpr const int &ObscureTheTruth(const int &a) { return a; } |
201 | constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}} |
202 | return ObscureTheTruth(b ? a : k); |
203 | } |
204 | static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok |
205 | constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}} |
206 | |
207 | constexpr const int MaybeReturnNonstaticRef(bool b, const int a) { |
208 | return ObscureTheTruth(b ? a : k); |
209 | } |
210 | static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok |
211 | constexpr int b = MaybeReturnNonstaticRef(true, 0); // ok |
212 | |
213 | constexpr int InternalReturnJunk(int n) { |
214 | return MaybeReturnJunk(true, n); // expected-note {{read of variable whose lifetime has ended}} |
215 | } |
216 | constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}} |
217 | |
218 | constexpr int LToR(int &n) { return n; } |
219 | constexpr int GrabCallersArgument(bool which, int a, int b) { |
220 | return LToR(which ? b : a); |
221 | } |
222 | static_assert(GrabCallersArgument(false, 1, 2) == 1, ""); |
223 | static_assert(GrabCallersArgument(true, 4, 8) == 8, ""); |
224 | |
225 | } |
226 | |
227 | namespace Pointers { |
228 | |
229 | constexpr int f(int n, const int *a, const int *b, const int *c) { |
230 | return n == 0 ? 0 : *a + f(n-1, b, c, a); |
231 | } |
232 | |
233 | const int x = 1, y = 10, z = 100; |
234 | static_assert(f(23, &x, &y, &z) == 788, ""); |
235 | |
236 | constexpr int g(int n, int a, int b, int c) { |
237 | return f(n, &a, &b, &c); |
238 | } |
239 | static_assert(g(23, x, y, z) == 788, ""); |
240 | |
241 | } |
242 | |
243 | namespace FunctionPointers { |
244 | |
245 | constexpr int Double(int n) { return 2 * n; } |
246 | constexpr int Triple(int n) { return 3 * n; } |
247 | constexpr int Twice(int (*F)(int), int n) { return F(F(n)); } |
248 | constexpr int Quadruple(int n) { return Twice(Double, n); } |
249 | constexpr auto Select(int n) -> int (*)(int) { |
250 | return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0; |
251 | } |
252 | constexpr int Apply(int (*F)(int), int n) { return F(n); } // expected-note {{subexpression}} |
253 | |
254 | static_assert(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, ""); |
255 | |
256 | constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'Apply(nullptr, 0)'}} |
257 | |
258 | } |
259 | |
260 | namespace PointerComparison { |
261 | |
262 | int x, y; |
263 | static_assert(&x == &y, "false"); // expected-error {{false}} |
264 | static_assert(&x != &y, ""); |
265 | constexpr bool g1 = &x == &y; |
266 | constexpr bool g2 = &x != &y; |
267 | constexpr bool g3 = &x <= &y; // expected-error {{must be initialized by a constant expression}} |
268 | constexpr bool g4 = &x >= &y; // expected-error {{must be initialized by a constant expression}} |
269 | constexpr bool g5 = &x < &y; // expected-error {{must be initialized by a constant expression}} |
270 | constexpr bool g6 = &x > &y; // expected-error {{must be initialized by a constant expression}} |
271 | |
272 | struct S { int x, y; } s; |
273 | static_assert(&s.x == &s.y, "false"); // expected-error {{false}} |
274 | static_assert(&s.x != &s.y, ""); |
275 | static_assert(&s.x <= &s.y, ""); |
276 | static_assert(&s.x >= &s.y, "false"); // expected-error {{false}} |
277 | static_assert(&s.x < &s.y, ""); |
278 | static_assert(&s.x > &s.y, "false"); // expected-error {{false}} |
279 | |
280 | static_assert(0 == &y, "false"); // expected-error {{false}} |
281 | static_assert(0 != &y, ""); |
282 | constexpr bool n3 = (int*)0 <= &y; // expected-error {{must be initialized by a constant expression}} |
283 | constexpr bool n4 = (int*)0 >= &y; // expected-error {{must be initialized by a constant expression}} |
284 | constexpr bool n5 = (int*)0 < &y; // expected-error {{must be initialized by a constant expression}} |
285 | constexpr bool n6 = (int*)0 > &y; // expected-error {{must be initialized by a constant expression}} |
286 | |
287 | static_assert(&x == 0, "false"); // expected-error {{false}} |
288 | static_assert(&x != 0, ""); |
289 | constexpr bool n9 = &x <= (int*)0; // expected-error {{must be initialized by a constant expression}} |
290 | constexpr bool n10 = &x >= (int*)0; // expected-error {{must be initialized by a constant expression}} |
291 | constexpr bool n11 = &x < (int*)0; // expected-error {{must be initialized by a constant expression}} |
292 | constexpr bool n12 = &x > (int*)0; // expected-error {{must be initialized by a constant expression}} |
293 | |
294 | static_assert(&x == &x, ""); |
295 | static_assert(&x != &x, "false"); // expected-error {{false}} |
296 | static_assert(&x <= &x, ""); |
297 | static_assert(&x >= &x, ""); |
298 | static_assert(&x < &x, "false"); // expected-error {{false}} |
299 | static_assert(&x > &x, "false"); // expected-error {{false}} |
300 | |
301 | constexpr S* sptr = &s; |
302 | constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr); // expected-error {{constant expression}} expected-note {{dynamic_cast}} |
303 | |
304 | struct U {}; |
305 | struct Str { |
306 | int a : dynamic_cast<S*>(sptr) == dynamic_cast<S*>(sptr); // \ |
307 | expected-warning {{not an integral constant expression}} \ |
308 | expected-note {{dynamic_cast is not allowed in a constant expression}} |
309 | int b : reinterpret_cast<S*>(sptr) == reinterpret_cast<S*>(sptr); // \ |
310 | expected-warning {{not an integral constant expression}} \ |
311 | expected-note {{reinterpret_cast is not allowed in a constant expression}} |
312 | int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \ |
313 | expected-warning {{not an integral constant expression}} \ |
314 | expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} |
315 | int d : (S*)(42) == (S*)(42); // \ |
316 | expected-warning {{not an integral constant expression}} \ |
317 | expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} |
318 | int e : (Str*)(sptr) == (Str*)(sptr); // \ |
319 | expected-warning {{not an integral constant expression}} \ |
320 | expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} |
321 | int f : &(U&)(*sptr) == &(U&)(*sptr); // \ |
322 | expected-warning {{not an integral constant expression}} \ |
323 | expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} |
324 | int g : (S*)(void*)(sptr) == sptr; // \ |
325 | expected-warning {{not an integral constant expression}} \ |
326 | expected-note {{cast from 'void *' is not allowed in a constant expression}} |
327 | }; |
328 | |
329 | extern char externalvar[]; |
330 | constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}} expected-note {{reinterpret_cast}} |
331 | constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} |
332 | static_assert(0 != "foo", ""); |
333 | |
334 | } |
335 | |
336 | namespace MaterializeTemporary { |
337 | |
338 | constexpr int f(const int &r) { return r; } |
339 | constexpr int n = f(1); |
340 | |
341 | constexpr bool same(const int &a, const int &b) { return &a == &b; } |
342 | constexpr bool sameTemporary(const int &n) { return same(n, n); } |
343 | |
344 | static_assert(n, ""); |
345 | static_assert(!same(4, 4), ""); |
346 | static_assert(same(n, n), ""); |
347 | static_assert(sameTemporary(9), ""); |
348 | |
349 | struct A { int &&r; }; |
350 | struct B { A &&a1; A &&a2; }; |
351 | |
352 | constexpr B b1 { { 1 }, { 2 } }; // expected-note {{temporary created here}} |
353 | static_assert(&b1.a1 != &b1.a2, ""); |
354 | static_assert(&b1.a1.r != &b1.a2.r, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} |
355 | |
356 | constexpr B &&b2 { { 3 }, { 4 } }; // expected-note {{temporary created here}} |
357 | static_assert(&b1 != &b2, ""); |
358 | static_assert(&b1.a1 != &b2.a1, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} |
359 | |
360 | constexpr thread_local B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} |
361 | void foo() { |
362 | constexpr static B b1 { { 1 }, { 2 } }; // ok |
363 | constexpr thread_local B b2 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} |
364 | constexpr B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} |
365 | } |
366 | |
367 | constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); |
368 | static_assert(&b4 != &b2, ""); |
369 | |
370 | // Proposed DR: copy-elision doesn't trigger lifetime extension. |
371 | constexpr B b5 = B{ {0}, {0} }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} |
372 | |
373 | namespace NestedNonStatic { |
374 | // Proposed DR: for a reference constant expression to refer to a static |
375 | // storage duration temporary, that temporary must itself be initialized |
376 | // by a constant expression (a core constant expression is not enough). |
377 | struct A { int &&r; }; |
378 | struct B { A &&a; }; |
379 | constexpr B a = { A{0} }; // ok |
380 | constexpr B b = { A(A{0}) }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} |
381 | } |
382 | |
383 | namespace FakeInitList { |
384 | struct init_list_3_ints { const int (&x)[3]; }; |
385 | struct init_list_2_init_list_3_ints { const init_list_3_ints (&x)[2]; }; |
386 | constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } }; |
387 | } |
388 | |
389 | namespace ConstAddedByReference { |
390 | const int &r = (0); |
391 | constexpr int n = r; |
392 | |
393 | struct A { constexpr operator int() const { return 0; }}; |
394 | struct B { constexpr operator const int() const { return 0; }}; |
395 | const int &ra = A(); |
396 | const int &rb = B(); |
397 | constexpr int na = ra; |
398 | constexpr int nb = rb; |
399 | } |
400 | |
401 | } |
402 | |
403 | constexpr int strcmp_ce(const char *p, const char *q) { |
404 | return (!*p || *p != *q) ? *p - *q : strcmp_ce(p+1, q+1); |
405 | } |
406 | |
407 | namespace StringLiteral { |
408 | |
409 | template<typename Char> |
410 | constexpr int MangleChars(const Char *p) { |
411 | return *p + 3 * (*p ? MangleChars(p+1) : 0); |
412 | } |
413 | |
414 | static_assert(MangleChars("constexpr!") == 1768383, ""); |
415 | static_assert(MangleChars(u8"constexpr!") == 1768383, ""); |
416 | static_assert(MangleChars(L"constexpr!") == 1768383, ""); |
417 | static_assert(MangleChars(u"constexpr!") == 1768383, ""); |
418 | static_assert(MangleChars(U"constexpr!") == 1768383, ""); |
419 | |
420 | constexpr char c0 = "nought index"[0]; |
421 | constexpr char c1 = "nice index"[10]; |
422 | constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}} |
423 | constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}} |
424 | constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that performs the conversions of a reinterpret_cast}} |
425 | |
426 | constexpr const char *p = "test" + 2; |
427 | static_assert(*p == 's', ""); |
428 | |
429 | constexpr const char *max_iter(const char *a, const char *b) { |
430 | return *a < *b ? b : a; |
431 | } |
432 | constexpr const char *max_element(const char *a, const char *b) { |
433 | return (a+1 >= b) ? a : max_iter(a, max_element(a+1, b)); |
434 | } |
435 | |
436 | constexpr char str[] = "the quick brown fox jumped over the lazy dog"; |
437 | constexpr const char *max = max_element(begin(str), end(str)); |
438 | static_assert(*max == 'z', ""); |
439 | static_assert(max == str + 38, ""); |
440 | |
441 | static_assert(strcmp_ce("hello world", "hello world") == 0, ""); |
442 | static_assert(strcmp_ce("hello world", "hello clang") > 0, ""); |
443 | static_assert(strcmp_ce("constexpr", "test") < 0, ""); |
444 | static_assert(strcmp_ce("", " ") < 0, ""); |
445 | |
446 | struct S { |
447 | int n : "foo"[4]; // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} |
448 | }; |
449 | |
450 | struct T { |
451 | char c[6]; |
452 | constexpr T() : c{"foo"} {} |
453 | }; |
454 | constexpr T t; |
455 | |
456 | static_assert(t.c[0] == 'f', ""); |
457 | static_assert(t.c[1] == 'o', ""); |
458 | static_assert(t.c[2] == 'o', ""); |
459 | static_assert(t.c[3] == 0, ""); |
460 | static_assert(t.c[4] == 0, ""); |
461 | static_assert(t.c[5] == 0, ""); |
462 | static_assert(t.c[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}} |
463 | |
464 | struct U { |
465 | wchar_t chars[6]; |
466 | int n; |
467 | } constexpr u = { { L"test" }, 0 }; |
468 | static_assert(u.chars[2] == L's', ""); |
469 | |
470 | struct V { |
471 | char c[4]; |
472 | constexpr V() : c("hi!") {} |
473 | }; |
474 | static_assert(V().c[1] == "i"[0], ""); |
475 | |
476 | namespace Parens { |
477 | constexpr unsigned char a[] = ("foo"), b[] = {"foo"}, c[] = {("foo")}, |
478 | d[4] = ("foo"), e[5] = {"foo"}, f[6] = {("foo")}; |
479 | static_assert(a[0] == 'f', ""); |
480 | static_assert(b[1] == 'o', ""); |
481 | static_assert(c[2] == 'o', ""); |
482 | static_assert(d[0] == 'f', ""); |
483 | static_assert(e[1] == 'o', ""); |
484 | static_assert(f[2] == 'o', ""); |
485 | static_assert(f[5] == 0, ""); |
486 | static_assert(f[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}} |
487 | } |
488 | |
489 | } |
490 | |
491 | namespace Array { |
492 | |
493 | template<typename Iter> |
494 | constexpr auto Sum(Iter begin, Iter end) -> decltype(+*begin) { |
495 | return begin == end ? 0 : *begin + Sum(begin+1, end); |
496 | } |
497 | |
498 | constexpr int xs[] = { 1, 2, 3, 4, 5 }; |
499 | constexpr int ys[] = { 5, 4, 3, 2, 1 }; |
500 | constexpr int sum_xs = Sum(begin(xs), end(xs)); |
501 | static_assert(sum_xs == 15, ""); |
502 | |
503 | constexpr int ZipFoldR(int (*F)(int x, int y, int c), int n, |
504 | const int *xs, const int *ys, int c) { |
505 | return n ? F( |
506 | *xs, // expected-note {{read of dereferenced one-past-the-end pointer}} |
507 | *ys, |
508 | ZipFoldR(F, n-1, xs+1, ys+1, c)) // \ |
509 | expected-note {{in call to 'ZipFoldR(&SubMul, 2, &xs[4], &ys[4], 1)'}} \ |
510 | expected-note {{in call to 'ZipFoldR(&SubMul, 1, &xs[5], &ys[5], 1)'}} |
511 | : c; |
512 | } |
513 | constexpr int MulAdd(int x, int y, int c) { return x * y + c; } |
514 | constexpr int InnerProduct = ZipFoldR(MulAdd, 5, xs, ys, 0); |
515 | static_assert(InnerProduct == 35, ""); |
516 | |
517 | constexpr int SubMul(int x, int y, int c) { return (x - y) * c; } |
518 | constexpr int DiffProd = ZipFoldR(SubMul, 2, xs+3, ys+3, 1); |
519 | static_assert(DiffProd == 8, ""); |
520 | static_assert(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // \ |
521 | expected-error {{constant expression}} \ |
522 | expected-note {{in call to 'ZipFoldR(&SubMul, 3, &xs[3], &ys[3], 1)'}} |
523 | |
524 | constexpr const int *p = xs + 3; |
525 | constexpr int xs4 = p[1]; // ok |
526 | constexpr int xs5 = p[2]; // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} |
527 | constexpr int xs6 = p[3]; // expected-error {{constant expression}} expected-note {{cannot refer to element 6}} |
528 | constexpr int xs0 = p[-3]; // ok |
529 | constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} |
530 | |
531 | constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // expected-note {{array 'zs' declared here}} |
532 | static_assert(zs[0][0][0][0] == 1, ""); |
533 | static_assert(zs[1][1][1][1] == 16, ""); |
534 | static_assert(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} |
535 | static_assert((&zs[0][0][0][2])[-1] == 2, ""); |
536 | static_assert(**(**(zs + 1) + 1) == 11, ""); |
537 | static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][-1] + 1) == 11, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1 of array of 2 elements in a constant expression}} |
538 | static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, ""); |
539 | constexpr int err_zs_1_2_0_0 = zs[1][2][0][0]; // \ |
540 | expected-error {{constant expression}} \ |
541 | expected-note {{cannot access array element of pointer past the end}} \ |
542 | expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} |
543 | |
544 | constexpr int fail(const int &p) { |
545 | return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}} |
546 | } |
547 | static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // \ |
548 | expected-error {{static_assert expression is not an integral constant expression}} \ |
549 | expected-note {{in call to 'fail(zs[1][0][1][0])'}} |
550 | |
551 | constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{C99 feature}} |
552 | constexpr int SumNonzero(const int *p) { |
553 | return *p + (*p ? SumNonzero(p+1) : 0); |
554 | } |
555 | constexpr int CountZero(const int *p, const int *q) { |
556 | return p == q ? 0 : (*p == 0) + CountZero(p+1, q); |
557 | } |
558 | static_assert(SumNonzero(arr) == 6, ""); |
559 | static_assert(CountZero(arr, arr + 40) == 36, ""); |
560 | |
561 | struct ArrayElem { |
562 | constexpr ArrayElem() : n(0) {} |
563 | int n; |
564 | constexpr int f() const { return n; } |
565 | }; |
566 | struct ArrayRVal { |
567 | constexpr ArrayRVal() {} |
568 | ArrayElem elems[10]; |
569 | }; |
570 | static_assert(ArrayRVal().elems[3].f() == 0, ""); |
571 | |
572 | namespace CopyCtor { |
573 | struct A { |
574 | constexpr A() {} |
575 | constexpr A(const A &) {} |
576 | }; |
577 | struct B { |
578 | A a; |
579 | int arr[10]; |
580 | }; |
581 | constexpr B b{{}, {1, 2, 3, 4, 5}}; |
582 | constexpr B c = b; |
583 | static_assert(c.arr[2] == 3, ""); |
584 | static_assert(c.arr[7] == 0, ""); |
585 | } |
586 | |
587 | constexpr int selfref[2][2][2] = { |
588 | selfref[1][1][1] + 1, selfref[0][0][0] + 1, |
589 | selfref[1][0][1] + 1, selfref[0][1][0] + 1, |
590 | selfref[1][0][0] + 1, selfref[0][1][1] + 1 }; |
591 | static_assert(selfref[0][0][0] == 1, ""); |
592 | static_assert(selfref[0][0][1] == 2, ""); |
593 | static_assert(selfref[0][1][0] == 1, ""); |
594 | static_assert(selfref[0][1][1] == 2, ""); |
595 | static_assert(selfref[1][0][0] == 1, ""); |
596 | static_assert(selfref[1][0][1] == 3, ""); |
597 | static_assert(selfref[1][1][0] == 0, ""); |
598 | static_assert(selfref[1][1][1] == 0, ""); |
599 | |
600 | struct TrivialDefCtor { int n; }; |
601 | typedef TrivialDefCtor TDCArray[2][2]; |
602 | static_assert(TDCArray{}[1][1].n == 0, ""); |
603 | |
604 | struct NonAggregateTDC : TrivialDefCtor {}; |
605 | typedef NonAggregateTDC NATDCArray[2][2]; |
606 | static_assert(NATDCArray{}[1][1].n == 0, ""); |
607 | |
608 | } |
609 | |
610 | // Per current CWG direction, we reject any cases where pointer arithmetic is |
611 | // not statically known to be valid. |
612 | namespace ArrayOfUnknownBound { |
613 | extern int arr[]; |
614 | constexpr int *a = arr; |
615 | constexpr int *b = &arr[0]; |
616 | static_assert(a == b, ""); |
617 | constexpr int *c = &arr[1]; // expected-error {{constant}} expected-note {{indexing of array without known bound}} |
618 | constexpr int *d = &a[1]; // expected-error {{constant}} expected-note {{indexing of array without known bound}} |
619 | constexpr int *e = a + 1; // expected-error {{constant}} expected-note {{indexing of array without known bound}} |
620 | |
621 | struct X { |
622 | int a; |
623 | int b[]; // expected-warning {{C99}} |
624 | }; |
625 | extern X x; |
626 | constexpr int *xb = x.b; // expected-error {{constant}} expected-note {{not supported}} |
627 | |
628 | struct Y { int a; }; |
629 | extern Y yarr[]; |
630 | constexpr Y *p = yarr; |
631 | constexpr int *q = &p->a; |
632 | |
633 | extern const int carr[]; // expected-note {{here}} |
634 | constexpr int n = carr[0]; // expected-error {{constant}} expected-note {{non-constexpr variable}} |
635 | |
636 | constexpr int local_extern[] = {1, 2, 3}; |
637 | void f() { extern const int local_extern[]; } |
638 | static_assert(local_extern[1] == 2, ""); |
639 | } |
640 | |
641 | namespace DependentValues { |
642 | |
643 | struct I { int n; typedef I V[10]; }; |
644 | I::V x, y; |
645 | int g(); // expected-note {{declared here}} |
646 | template<bool B, typename T> struct S : T { |
647 | int k; |
648 | void f() { |
649 | I::V &cells = B ? x : y; |
650 | I &i = cells[k]; |
651 | switch (i.n) {} |
652 | |
653 | constexpr int n = g(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr function 'g'}} |
654 | |
655 | constexpr int m = this->g(); // ok, could be constexpr |
656 | } |
657 | }; |
658 | |
659 | extern const int n; |
660 | template<typename T> void f() { |
661 | // This is ill-formed, because a hypothetical instantiation at the point of |
662 | // template definition would be ill-formed due to a construct that does not |
663 | // depend on a template parameter. |
664 | constexpr int k = n; // expected-error {{must be initialized by a constant expression}} |
665 | } |
666 | // It doesn't matter that the instantiation could later become valid: |
667 | constexpr int n = 4; |
668 | template void f<int>(); |
669 | |
670 | } |
671 | |
672 | namespace Class { |
673 | |
674 | struct A { constexpr A(int a, int b) : k(a + b) {} int k; }; |
675 | constexpr int fn(const A &a) { return a.k; } |
676 | static_assert(fn(A(4,5)) == 9, ""); |
677 | |
678 | struct B { int n; int m; } constexpr b = { 0, b.n }; |
679 | struct C { |
680 | constexpr C(C *this_) : m(42), n(this_->m) {} // ok |
681 | int m, n; |
682 | }; |
683 | struct D { |
684 | C c; |
685 | constexpr D() : c(&c) {} |
686 | }; |
687 | static_assert(D().c.n == 42, ""); |
688 | |
689 | struct E { |
690 | constexpr E() : p(&p) {} |
691 | void *p; |
692 | }; |
693 | constexpr const E &e1 = E(); |
694 | // This is a constant expression if we elide the copy constructor call, and |
695 | // is not a constant expression if we don't! But we do, so it is. |
696 | constexpr E e2 = E(); |
697 | static_assert(e2.p == &e2.p, ""); |
698 | constexpr E e3; |
699 | static_assert(e3.p == &e3.p, ""); |
700 | |
701 | extern const class F f; |
702 | struct F { |
703 | constexpr F() : p(&f.p) {} |
704 | const void *p; |
705 | }; |
706 | constexpr F f; |
707 | |
708 | struct G { |
709 | struct T { |
710 | constexpr T(T *p) : u1(), u2(p) {} |
711 | union U1 { |
712 | constexpr U1() {} |
713 | int a, b = 42; |
714 | } u1; |
715 | union U2 { |
716 | constexpr U2(T *p) : c(p->u1.b) {} |
717 | int c, d; |
718 | } u2; |
719 | } t; |
720 | constexpr G() : t(&t) {} |
721 | } constexpr g; |
722 | |
723 | static_assert(g.t.u1.a == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'a' of union with active member 'b'}} |
724 | static_assert(g.t.u1.b == 42, ""); |
725 | static_assert(g.t.u2.c == 42, ""); |
726 | static_assert(g.t.u2.d == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'd' of union with active member 'c'}} |
727 | |
728 | struct S { |
729 | int a, b; |
730 | const S *p; |
731 | double d; |
732 | const char *q; |
733 | |
734 | constexpr S(int n, const S *p) : a(5), b(n), p(p), d(n), q("hello") {} |
735 | }; |
736 | |
737 | S global(43, &global); |
738 | |
739 | static_assert(S(15, &global).b == 15, ""); |
740 | |
741 | constexpr bool CheckS(const S &s) { |
742 | return s.a == 5 && s.b == 27 && s.p == &global && s.d == 27. && s.q[3] == 'l'; |
743 | } |
744 | static_assert(CheckS(S(27, &global)), ""); |
745 | |
746 | struct Arr { |
747 | char arr[3]; |
748 | constexpr Arr() : arr{'x', 'y', 'z'} {} |
749 | }; |
750 | constexpr int hash(Arr &&a) { |
751 | return a.arr[0] + a.arr[1] * 0x100 + a.arr[2] * 0x10000; |
752 | } |
753 | constexpr int k = hash(Arr()); |
754 | static_assert(k == 0x007a7978, ""); |
755 | |
756 | |
757 | struct AggregateInit { |
758 | const char &c; |
759 | int n; |
760 | double d; |
761 | int arr[5]; |
762 | void *p; |
763 | }; |
764 | |
765 | constexpr AggregateInit agg1 = { "hello"[0] }; |
766 | |
767 | static_assert(strcmp_ce(&agg1.c, "hello") == 0, ""); |
768 | static_assert(agg1.n == 0, ""); |
769 | static_assert(agg1.d == 0.0, ""); |
770 | static_assert(agg1.arr[-1] == 0, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} |
771 | static_assert(agg1.arr[0] == 0, ""); |
772 | static_assert(agg1.arr[4] == 0, ""); |
773 | static_assert(agg1.arr[5] == 0, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end}} |
774 | static_assert(agg1.p == nullptr, ""); |
775 | |
776 | static constexpr const unsigned char uc[] = { "foo" }; |
777 | static_assert(uc[0] == 'f', ""); |
778 | static_assert(uc[3] == 0, ""); |
779 | |
780 | namespace SimpleDerivedClass { |
781 | |
782 | struct B { |
783 | constexpr B(int n) : a(n) {} |
784 | int a; |
785 | }; |
786 | struct D : B { |
787 | constexpr D(int n) : B(n) {} |
788 | }; |
789 | constexpr D d(3); |
790 | static_assert(d.a == 3, ""); |
791 | |
792 | } |
793 | |
794 | struct Bottom { constexpr Bottom() {} }; |
795 | struct Base : Bottom { |
796 | constexpr Base(int a = 42, const char *b = "test") : a(a), b(b) {} |
797 | int a; |
798 | const char *b; |
799 | }; |
800 | struct Base2 : Bottom { |
801 | constexpr Base2(const int &r) : r(r) {} |
802 | int q = 123; |
803 | const int &r; |
804 | }; |
805 | struct Derived : Base, Base2 { |
806 | constexpr Derived() : Base(76), Base2(a) {} |
807 | int c = r + b[1]; |
808 | }; |
809 | |
810 | constexpr bool operator==(const Base &a, const Base &b) { |
811 | return a.a == b.a && strcmp_ce(a.b, b.b) == 0; |
812 | } |
813 | |
814 | constexpr Base base; |
815 | constexpr Base base2(76); |
816 | constexpr Derived derived; |
817 | static_assert(derived.a == 76, ""); |
818 | static_assert(derived.b[2] == 's', ""); |
819 | static_assert(derived.c == 76 + 'e', ""); |
820 | static_assert(derived.q == 123, ""); |
821 | static_assert(derived.r == 76, ""); |
822 | static_assert(&derived.r == &derived.a, ""); |
823 | |
824 | static_assert(!(derived == base), ""); |
825 | static_assert(derived == base2, ""); |
826 | |
827 | constexpr Bottom &bot1 = (Base&)derived; |
828 | constexpr Bottom &bot2 = (Base2&)derived; |
829 | static_assert(&bot1 != &bot2, ""); |
830 | |
831 | constexpr Bottom *pb1 = (Base*)&derived; |
832 | constexpr Bottom *pb2 = (Base2*)&derived; |
833 | static_assert(&pb1 != &pb2, ""); |
834 | static_assert(pb1 == &bot1, ""); |
835 | static_assert(pb2 == &bot2, ""); |
836 | |
837 | constexpr Base2 &fail = (Base2&)bot1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}} |
838 | constexpr Base &fail2 = (Base&)*pb2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}} |
839 | constexpr Base2 &ok2 = (Base2&)bot2; |
840 | static_assert(&ok2 == &derived, ""); |
841 | |
842 | constexpr Base2 *pfail = (Base2*)pb1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}} |
843 | constexpr Base *pfail2 = (Base*)&bot2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}} |
844 | constexpr Base2 *pok2 = (Base2*)pb2; |
845 | static_assert(pok2 == &derived, ""); |
846 | static_assert(&ok2 == pok2, ""); |
847 | static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, ""); |
848 | static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, ""); |
849 | |
850 | // Core issue 903: we do not perform constant evaluation when checking for a |
851 | // null pointer in C++11. Just check for an integer literal with value 0. |
852 | constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Class::Base *const' with an rvalue of type 'int'}} |
853 | constexpr Base *nullB1 = 0; |
854 | static_assert((Bottom*)nullB == 0, ""); |
855 | static_assert((Derived*)nullB == 0, ""); |
856 | static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, ""); |
857 | Base *nullB2 = '\0'; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'char'}} |
858 | Base *nullB3 = (0); |
859 | Base *nullB4 = false; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'bool'}} |
860 | Base *nullB5 = ((0ULL)); |
861 | Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'double'}} |
862 | enum Null { kNull }; |
863 | Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'Class::Null'}} |
864 | static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}} |
865 | |
866 | |
867 | |
868 | namespace ConversionOperators { |
869 | |
870 | struct T { |
871 | constexpr T(int n) : k(5*n - 3) {} |
872 | constexpr operator int() const { return k; } |
873 | int k; |
874 | }; |
875 | |
876 | struct S { |
877 | constexpr S(int n) : k(2*n + 1) {} |
878 | constexpr operator int() const { return k; } |
879 | constexpr operator T() const { return T(k); } |
880 | int k; |
881 | }; |
882 | |
883 | constexpr bool check(T a, T b) { return a == b.k; } |
884 | |
885 | static_assert(S(5) == 11, ""); |
886 | static_assert(check(S(5), 11), ""); |
887 | |
888 | namespace PR14171 { |
889 | |
890 | struct X { |
891 | constexpr (operator int)() const { return 0; } |
892 | }; |
893 | static_assert(X() == 0, ""); |
894 | |
895 | } |
896 | |
897 | } |
898 | |
899 | struct This { |
900 | constexpr int f() const { return 0; } |
901 | static constexpr int g() { return 0; } |
902 | void h() { |
903 | constexpr int x = f(); // expected-error {{must be initialized by a constant}} |
904 | // expected-note@-1 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}} |
905 | constexpr int y = this->f(); // expected-error {{must be initialized by a constant}} |
906 | // expected-note-re@-1 {{{{^}}use of 'this' pointer}} |
907 | constexpr int z = g(); |
908 | static_assert(z == 0, ""); |
909 | } |
910 | }; |
911 | |
912 | } |
913 | |
914 | namespace Temporaries { |
915 | |
916 | struct S { |
917 | constexpr S() {} |
918 | constexpr int f() const; |
919 | constexpr int g() const; |
920 | }; |
921 | struct T : S { |
922 | constexpr T(int n) : S(), n(n) {} |
923 | int n; |
924 | }; |
925 | constexpr int S::f() const { |
926 | return static_cast<const T*>(this)->n; // expected-note {{cannot cast}} |
927 | } |
928 | constexpr int S::g() const { |
929 | // FIXME: Better diagnostic for this. |
930 | return this->*(int(S::*))&T::n; // expected-note {{subexpression}} |
931 | } |
932 | // The T temporary is implicitly cast to an S subobject, but we can recover the |
933 | // T full-object via a base-to-derived cast, or a derived-to-base-casted member |
934 | // pointer. |
935 | static_assert(S().f(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->f()'}} |
936 | static_assert(S().g(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->g()'}} |
937 | static_assert(T(3).f() == 3, ""); |
938 | static_assert(T(4).g() == 4, ""); |
939 | |
940 | constexpr int f(const S &s) { |
941 | return static_cast<const T&>(s).n; |
942 | } |
943 | constexpr int n = f(T(5)); |
944 | static_assert(f(T(5)) == 5, ""); |
945 | |
946 | constexpr bool b(int n) { return &n; } |
947 | static_assert(b(0), ""); |
948 | |
949 | struct NonLiteral { |
950 | NonLiteral(); |
951 | int f(); |
952 | }; |
953 | constexpr int k = NonLiteral().f(); // expected-error {{constant expression}} expected-note {{non-literal type 'Temporaries::NonLiteral'}} |
954 | |
955 | } |
956 | |
957 | namespace Union { |
958 | |
959 | union U { |
960 | int a; |
961 | int b; |
962 | }; |
963 | |
964 | constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{C99 feature}} |
965 | static_assert(u[0].a == 0, ""); |
966 | static_assert(u[0].b, ""); // expected-error {{constant expression}} expected-note {{read of member 'b' of union with active member 'a'}} |
967 | static_assert(u[1].b == 1, ""); |
968 | static_assert((&u[1].b)[1] == 2, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} |
969 | static_assert(*(&(u[1].b) + 1 + 1) == 3, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element 2 of non-array object}} |
970 | static_assert((&(u[1]) + 1 + 1)->b == 3, ""); |
971 | |
972 | constexpr U v = {}; |
973 | static_assert(v.a == 0, ""); |
974 | |
975 | union Empty {}; |
976 | constexpr Empty e = {}; |
977 | |
978 | // Make sure we handle trivial copy constructors for unions. |
979 | constexpr U x = {42}; |
980 | constexpr U y = x; |
981 | static_assert(y.a == 42, ""); |
982 | static_assert(y.b == 42, ""); // expected-error {{constant expression}} expected-note {{'b' of union with active member 'a'}} |
983 | |
984 | } |
985 | |
986 | namespace MemberPointer { |
987 | struct A { |
988 | constexpr A(int n) : n(n) {} |
989 | int n; |
990 | constexpr int f() const { return n + 3; } |
991 | }; |
992 | constexpr A a(7); |
993 | static_assert(A(5).*&A::n == 5, ""); |
994 | static_assert((&a)->*&A::n == 7, ""); |
995 | static_assert((A(8).*&A::f)() == 11, ""); |
996 | static_assert(((&a)->*&A::f)() == 10, ""); |
997 | |
998 | struct B : A { |
999 | constexpr B(int n, int m) : A(n), m(m) {} |
1000 | int m; |
1001 | constexpr int g() const { return n + m + 1; } |
1002 | }; |
1003 | constexpr B b(9, 13); |
1004 | static_assert(B(4, 11).*&A::n == 4, ""); |
1005 | static_assert(B(4, 11).*&B::m == 11, ""); |
1006 | static_assert(B(4, 11).*(int(A::*))&B::m == 11, ""); |
1007 | static_assert((&b)->*&A::n == 9, ""); |
1008 | static_assert((&b)->*&B::m == 13, ""); |
1009 | static_assert((&b)->*(int(A::*))&B::m == 13, ""); |
1010 | static_assert((B(4, 11).*&A::f)() == 7, ""); |
1011 | static_assert((B(4, 11).*&B::g)() == 16, ""); |
1012 | static_assert((B(4, 11).*(int(A::*)()const)&B::g)() == 16, ""); |
1013 | static_assert(((&b)->*&A::f)() == 12, ""); |
1014 | static_assert(((&b)->*&B::g)() == 23, ""); |
1015 | static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, ""); |
1016 | |
1017 | struct S { |
1018 | constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) : |
1019 | m(m), n(n), pf(pf), pn(pn) {} |
1020 | constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {} |
1021 | |
1022 | constexpr int f() const { return this->*pn; } |
1023 | virtual int g() const; |
1024 | |
1025 | int m, n; |
1026 | int (S::*pf)() const; |
1027 | int S::*pn; |
1028 | }; |
1029 | |
1030 | constexpr int S::*pm = &S::m; |
1031 | constexpr int S::*pn = &S::n; |
1032 | constexpr int (S::*pf)() const = &S::f; |
1033 | constexpr int (S::*pg)() const = &S::g; |
1034 | |
1035 | constexpr S s(2, 5, &S::f, &S::m); |
1036 | |
1037 | static_assert((s.*&S::f)() == 2, ""); |
1038 | static_assert((s.*s.pf)() == 2, ""); |
1039 | |
1040 | static_assert(pf == &S::f, ""); |
1041 | static_assert(pf == s.*&S::pf, ""); |
1042 | static_assert(pm == &S::m, ""); |
1043 | static_assert(pm != pn, ""); |
1044 | static_assert(s.pn != pn, ""); |
1045 | static_assert(s.pn == pm, ""); |
1046 | static_assert(pg != nullptr, ""); |
1047 | static_assert(pf != nullptr, ""); |
1048 | static_assert((int S::*)nullptr == nullptr, ""); |
1049 | static_assert(pg == pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}} |
1050 | static_assert(pf != pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}} |
1051 | |
1052 | template<int n> struct T : T<n-1> {}; |
1053 | template<> struct T<0> { int n; }; |
1054 | template<> struct T<30> : T<29> { int m; }; |
1055 | |
1056 | T<17> t17; |
1057 | T<30> t30; |
1058 | |
1059 | constexpr int (T<10>::*deepn) = &T<0>::n; |
1060 | static_assert(&(t17.*deepn) == &t17.n, ""); |
1061 | static_assert(deepn == &T<2>::n, ""); |
1062 | |
1063 | constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m; |
1064 | constexpr int *pbad = &(t17.*deepm); // expected-error {{constant expression}} |
1065 | static_assert(&(t30.*deepm) == &t30.m, ""); |
1066 | static_assert(deepm == &T<50>::m, ""); |
1067 | static_assert(deepm != deepn, ""); |
1068 | |
1069 | constexpr T<5> *p17_5 = &t17; |
1070 | constexpr T<13> *p17_13 = (T<13>*)p17_5; |
1071 | constexpr T<23> *p17_23 = (T<23>*)p17_13; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'T<17>' to type 'T<23>'}} |
1072 | static_assert(&(p17_5->*(int(T<3>::*))deepn) == &t17.n, ""); |
1073 | static_assert(&(p17_13->*deepn) == &t17.n, ""); |
1074 | constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // expected-error {{constant expression}} |
1075 | |
1076 | constexpr T<5> *p30_5 = &t30; |
1077 | constexpr T<23> *p30_23 = (T<23>*)p30_5; |
1078 | constexpr T<13> *p30_13 = p30_23; |
1079 | static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, ""); |
1080 | static_assert(&(p30_13->*deepn) == &t30.n, ""); |
1081 | static_assert(&(p30_23->*deepn) == &t30.n, ""); |
1082 | static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, ""); |
1083 | static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, ""); |
1084 | static_assert(&(p30_23->*deepm) == &t30.m, ""); |
1085 | |
1086 | struct Base { int n; }; |
1087 | template<int N> struct Mid : Base {}; |
1088 | struct Derived : Mid<0>, Mid<1> {}; |
1089 | static_assert(&Mid<0>::n == &Mid<1>::n, ""); |
1090 | static_assert((int Derived::*)(int Mid<0>::*)&Mid<0>::n != |
1091 | (int Derived::*)(int Mid<1>::*)&Mid<1>::n, ""); |
1092 | static_assert(&Mid<0>::n == (int Mid<0>::*)&Base::n, ""); |
1093 | } |
1094 | |
1095 | namespace ArrayBaseDerived { |
1096 | |
1097 | struct Base { |
1098 | constexpr Base() {} |
1099 | int n = 0; |
1100 | }; |
1101 | struct Derived : Base { |
1102 | constexpr Derived() {} |
1103 | constexpr const int *f() const { return &n; } |
1104 | }; |
1105 | |
1106 | constexpr Derived a[10]; |
1107 | constexpr Derived *pd3 = const_cast<Derived*>(&a[3]); |
1108 | constexpr Base *pb3 = const_cast<Derived*>(&a[3]); |
1109 | static_assert(pb3 == pd3, ""); |
1110 | |
1111 | // pb3 does not point to an array element. |
1112 | constexpr Base *pb4 = pb3 + 1; // ok, one-past-the-end pointer. |
1113 | constexpr int pb4n = pb4->n; // expected-error {{constant expression}} expected-note {{cannot access field of pointer past the end}} |
1114 | constexpr Base *err_pb5 = pb3 + 2; // expected-error {{constant expression}} expected-note {{cannot refer to element 2}} expected-note {{here}} |
1115 | constexpr int err_pb5n = err_pb5->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb5' is not a constant expression}} |
1116 | constexpr Base *err_pb2 = pb3 - 1; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} expected-note {{here}} |
1117 | constexpr int err_pb2n = err_pb2->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb2'}} |
1118 | constexpr Base *pb3a = pb4 - 1; |
1119 | |
1120 | // pb4 does not point to a Derived. |
1121 | constexpr Derived *err_pd4 = (Derived*)pb4; // expected-error {{constant expression}} expected-note {{cannot access derived class of pointer past the end}} |
1122 | constexpr Derived *pd3a = (Derived*)pb3a; |
1123 | constexpr int pd3n = pd3a->n; |
1124 | |
1125 | // pd3a still points to the Derived array. |
1126 | constexpr Derived *pd6 = pd3a + 3; |
1127 | static_assert(pd6 == &a[6], ""); |
1128 | constexpr Derived *pd9 = pd6 + 3; |
1129 | constexpr Derived *pd10 = pd6 + 4; |
1130 | constexpr int pd9n = pd9->n; // ok |
1131 | constexpr int err_pd10n = pd10->n; // expected-error {{constant expression}} expected-note {{cannot access base class of pointer past the end}} |
1132 | constexpr int pd0n = pd10[-10].n; |
1133 | constexpr int err_pdminus1n = pd10[-11].n; // expected-error {{constant expression}} expected-note {{cannot refer to element -1 of}} |
1134 | |
1135 | constexpr Base *pb9 = pd9; |
1136 | constexpr const int *(Base::*pfb)() const = |
1137 | static_cast<const int *(Base::*)() const>(&Derived::f); |
1138 | static_assert((pb9->*pfb)() == &a[9].n, ""); |
1139 | } |
1140 | |
1141 | namespace Complex { |
1142 | |
1143 | class complex { |
1144 | int re, im; |
1145 | public: |
1146 | constexpr complex(int re = 0, int im = 0) : re(re), im(im) {} |
1147 | constexpr complex(const complex &o) : re(o.re), im(o.im) {} |
1148 | constexpr complex operator-() const { return complex(-re, -im); } |
1149 | friend constexpr complex operator+(const complex &l, const complex &r) { |
1150 | return complex(l.re + r.re, l.im + r.im); |
1151 | } |
1152 | friend constexpr complex operator-(const complex &l, const complex &r) { |
1153 | return l + -r; |
1154 | } |
1155 | friend constexpr complex operator*(const complex &l, const complex &r) { |
1156 | return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re); |
1157 | } |
1158 | friend constexpr bool operator==(const complex &l, const complex &r) { |
1159 | return l.re == r.re && l.im == r.im; |
1160 | } |
1161 | constexpr bool operator!=(const complex &r) const { |
1162 | return re != r.re || im != r.im; |
1163 | } |
1164 | constexpr int real() const { return re; } |
1165 | constexpr int imag() const { return im; } |
1166 | }; |
1167 | |
1168 | constexpr complex i = complex(0, 1); |
1169 | constexpr complex k = (3 + 4*i) * (6 - 4*i); |
1170 | static_assert(complex(1,0).real() == 1, ""); |
1171 | static_assert(complex(1,0).imag() == 0, ""); |
1172 | static_assert(((complex)1).imag() == 0, ""); |
1173 | static_assert(k.real() == 34, ""); |
1174 | static_assert(k.imag() == 12, ""); |
1175 | static_assert(k - 34 == 12*i, ""); |
1176 | static_assert((complex)1 == complex(1), ""); |
1177 | static_assert((complex)1 != complex(0, 1), ""); |
1178 | static_assert(complex(1) == complex(1), ""); |
1179 | static_assert(complex(1) != complex(0, 1), ""); |
1180 | constexpr complex makeComplex(int re, int im) { return complex(re, im); } |
1181 | static_assert(makeComplex(1,0) == complex(1), ""); |
1182 | static_assert(makeComplex(1,0) != complex(0, 1), ""); |
1183 | |
1184 | class complex_wrap : public complex { |
1185 | public: |
1186 | constexpr complex_wrap(int re, int im = 0) : complex(re, im) {} |
1187 | constexpr complex_wrap(const complex_wrap &o) : complex(o) {} |
1188 | }; |
1189 | |
1190 | static_assert((complex_wrap)1 == complex(1), ""); |
1191 | static_assert((complex)1 != complex_wrap(0, 1), ""); |
1192 | static_assert(complex(1) == complex_wrap(1), ""); |
1193 | static_assert(complex_wrap(1) != complex(0, 1), ""); |
1194 | constexpr complex_wrap makeComplexWrap(int re, int im) { |
1195 | return complex_wrap(re, im); |
1196 | } |
1197 | static_assert(makeComplexWrap(1,0) == complex(1), ""); |
1198 | static_assert(makeComplexWrap(1,0) != complex(0, 1), ""); |
1199 | |
1200 | } |
1201 | |
1202 | namespace PR11595 { |
1203 | struct A { constexpr bool operator==(int x) const { return true; } }; |
1204 | struct B { B(); A& x; }; |
1205 | static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}} |
1206 | |
1207 | constexpr bool f(int k) { // expected-error {{constexpr function never produces a constant expression}} |
1208 | return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}} |
1209 | } |
1210 | } |
1211 | |
1212 | namespace ExprWithCleanups { |
1213 | struct A { A(); ~A(); int get(); }; |
1214 | constexpr int get(bool FromA) { return FromA ? A().get() : 1; } |
1215 | constexpr int n = get(false); |
1216 | } |
1217 | |
1218 | namespace Volatile { |
1219 | |
1220 | volatile constexpr int n1 = 0; // expected-note {{here}} |
1221 | volatile const int n2 = 0; // expected-note {{here}} |
1222 | int n3 = 37; // expected-note {{declared here}} |
1223 | |
1224 | constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}} |
1225 | constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}} |
1226 | constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}} |
1227 | constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}} |
1228 | |
1229 | struct T { int n; }; |
1230 | const T t = { 42 }; |
1231 | |
1232 | constexpr int f(volatile int &&r) { |
1233 | return r; // expected-note {{read of volatile-qualified type 'volatile int'}} |
1234 | } |
1235 | constexpr int g(volatile int &&r) { |
1236 | return const_cast<int&>(r); // expected-note {{read of volatile temporary is not allowed in a constant expression}} |
1237 | } |
1238 | struct S { |
1239 | int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}} |
1240 | int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}} |
1241 | int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}} |
1242 | int m : t.n; // expected-warning{{width of bit-field 'm' (42 bits)}} expected-warning{{expression is not an integral constant expression}} expected-note{{read of non-constexpr variable 't' is not allowed}} |
1243 | }; |
1244 | |
1245 | } |
1246 | |
1247 | namespace ExternConstexpr { |
1248 | extern constexpr int n = 0; |
1249 | extern constexpr int m; // expected-error {{constexpr variable declaration must be a definition}} |
1250 | void f() { |
1251 | extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}} |
1252 | constexpr int j = 0; |
1253 | constexpr int k; // expected-error {{default initialization of an object of const type}} |
1254 | } |
1255 | |
1256 | extern const int q; |
1257 | constexpr int g() { return q; } |
1258 | constexpr int q = g(); |
1259 | static_assert(q == 0, "zero-initialization should precede static initialization"); |
1260 | |
1261 | extern int r; // expected-note {{here}} |
1262 | constexpr int h() { return r; } // expected-error {{never produces a constant}} expected-note {{read of non-const}} |
1263 | |
1264 | struct S { int n; }; |
1265 | extern const S s; |
1266 | constexpr int x() { return s.n; } |
1267 | constexpr S s = {x()}; |
1268 | static_assert(s.n == 0, "zero-initialization should precede static initialization"); |
1269 | } |
1270 | |
1271 | namespace ComplexConstexpr { |
1272 | constexpr _Complex float test1 = {}; |
1273 | constexpr _Complex float test2 = {1}; |
1274 | constexpr _Complex double test3 = {1,2}; |
1275 | constexpr _Complex int test4 = {4}; |
1276 | constexpr _Complex int test5 = 4; |
1277 | constexpr _Complex int test6 = {5,6}; |
1278 | typedef _Complex float fcomplex; |
1279 | constexpr fcomplex test7 = fcomplex(); |
1280 | |
1281 | constexpr const double &t2r = __real test3; |
1282 | constexpr const double &t2i = __imag test3; |
1283 | static_assert(&t2r + 1 == &t2i, ""); |
1284 | static_assert(t2r == 1.0, ""); |
1285 | static_assert(t2i == 2.0, ""); |
1286 | constexpr const double *t2p = &t2r; |
1287 | static_assert(t2p[-1] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element -1 of array of 2 elements}} |
1288 | static_assert(t2p[0] == 1.0, ""); |
1289 | static_assert(t2p[1] == 2.0, ""); |
1290 | static_assert(t2p[2] == 0.0, ""); // expected-error {{constant expr}} expected-note {{one-past-the-end pointer}} |
1291 | static_assert(t2p[3] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element 3 of array of 2 elements}} |
1292 | constexpr _Complex float *p = 0; |
1293 | constexpr float pr = __real *p; // expected-error {{constant expr}} expected-note {{cannot access real component of null}} |
1294 | constexpr float pi = __imag *p; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of null}} |
1295 | constexpr const _Complex double *q = &test3 + 1; |
1296 | constexpr double qr = __real *q; // expected-error {{constant expr}} expected-note {{cannot access real component of pointer past the end}} |
1297 | constexpr double qi = __imag *q; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of pointer past the end}} |
1298 | |
1299 | static_assert(__real test6 == 5, ""); |
1300 | static_assert(__imag test6 == 6, ""); |
1301 | static_assert(&__imag test6 == &__real test6 + 1, ""); |
1302 | } |
1303 | |
1304 | // _Atomic(T) is exactly like T for the purposes of constant expression |
1305 | // evaluation.. |
1306 | namespace Atomic { |
1307 | constexpr _Atomic int n = 3; |
1308 | |
1309 | struct S { _Atomic(double) d; }; |
1310 | constexpr S s = { 0.5 }; |
1311 | constexpr double d1 = s.d; |
1312 | constexpr double d2 = n; |
1313 | constexpr _Atomic double d3 = n; |
1314 | |
1315 | constexpr _Atomic(int) n2 = d3; |
1316 | static_assert(d1 == 0.5, ""); |
1317 | static_assert(d3 == 3.0, ""); |
1318 | |
1319 | namespace PR16056 { |
1320 | struct TestVar { |
1321 | _Atomic(int) value; |
1322 | constexpr TestVar(int value) : value(value) {} |
1323 | }; |
1324 | constexpr TestVar testVar{-1}; |
1325 | static_assert(testVar.value == -1, ""); |
1326 | } |
1327 | |
1328 | namespace PR32034 { |
1329 | struct A {}; |
1330 | struct B { _Atomic(A) a; }; |
1331 | constexpr int n = (B(), B(), 0); |
1332 | |
1333 | struct C { constexpr C() {} void *self = this; }; |
1334 | constexpr _Atomic(C) c = C(); |
1335 | } |
1336 | } |
1337 | |
1338 | namespace InstantiateCaseStmt { |
1339 | template<int x> constexpr int f() { return x; } |
1340 | template<int x> int g(int c) { switch(c) { case f<x>(): return 1; } return 0; } |
1341 | int gg(int c) { return g<4>(c); } |
1342 | } |
1343 | |
1344 | namespace ConvertedConstantExpr { |
1345 | extern int &m; |
1346 | extern int &n; |
1347 | |
1348 | constexpr int k = 4; |
1349 | int &m = const_cast<int&>(k); |
1350 | |
1351 | // If we have nothing more interesting to say, ensure we don't produce a |
1352 | // useless note and instead just point to the non-constant subexpression. |
1353 | enum class E { |
1354 | em = m, |
1355 | en = n, // expected-error {{not a constant expression}} |
1356 | eo = (m + |
1357 | n // expected-error {{not a constant expression}} |
1358 | ), |
1359 | eq = reinterpret_cast<long>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}} |
1360 | }; |
1361 | } |
1362 | |
1363 | namespace IndirectField { |
1364 | struct S { |
1365 | struct { // expected-warning {{GNU extension}} |
1366 | union { // expected-warning {{declared in an anonymous struct}} |
1367 | struct { // expected-warning {{GNU extension}} expected-warning {{declared in an anonymous union}} |
1368 | int a; |
1369 | int b; |
1370 | }; |
1371 | int c; |
1372 | }; |
1373 | int d; |
1374 | }; |
1375 | union { |
1376 | int e; |
1377 | int f; |
1378 | }; |
1379 | constexpr S(int a, int b, int d, int e) : a(a), b(b), d(d), e(e) {} |
1380 | constexpr S(int c, int d, int f) : c(c), d(d), f(f) {} |
1381 | }; |
1382 | |
1383 | constexpr S s1(1, 2, 3, 4); |
1384 | constexpr S s2(5, 6, 7); |
1385 | |
1386 | // FIXME: The diagnostics here do a very poor job of explaining which unnamed |
1387 | // member is active and which is requested. |
1388 | static_assert(s1.a == 1, ""); |
1389 | static_assert(s1.b == 2, ""); |
1390 | static_assert(s1.c == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} |
1391 | static_assert(s1.d == 3, ""); |
1392 | static_assert(s1.e == 4, ""); |
1393 | static_assert(s1.f == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} |
1394 | |
1395 | static_assert(s2.a == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} |
1396 | static_assert(s2.b == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} |
1397 | static_assert(s2.c == 5, ""); |
1398 | static_assert(s2.d == 6, ""); |
1399 | static_assert(s2.e == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} |
1400 | static_assert(s2.f == 7, ""); |
1401 | } |
1402 | |
1403 | // DR1405: don't allow reading mutable members in constant expressions. |
1404 | namespace MutableMembers { |
1405 | struct MM { |
1406 | mutable int n; // expected-note 3{{declared here}} |
1407 | } constexpr mm = { 4 }; |
1408 | constexpr int mmn = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}} |
1409 | int x = (mm.n = 1, 3); |
1410 | constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}} |
1411 | |
1412 | // Here's one reason why allowing this would be a disaster... |
1413 | template<int n> struct Id { int k = n; }; |
1414 | int f() { |
1415 | constexpr MM m = { 0 }; |
1416 | ++m.n; |
1417 | return Id<m.n>().k; // expected-error {{not a constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}} |
1418 | } |
1419 | |
1420 | struct A { int n; }; |
1421 | struct B { mutable A a; }; // expected-note {{here}} |
1422 | struct C { B b; }; |
1423 | constexpr C c[3] = {}; |
1424 | constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}} |
1425 | |
1426 | struct D { int x; mutable int y; }; // expected-note {{here}} |
1427 | constexpr D d1 = { 1, 2 }; |
1428 | int l = ++d1.y; |
1429 | constexpr D d2 = d1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} |
1430 | |
1431 | struct E { |
1432 | union { |
1433 | int a; |
1434 | mutable int b; // expected-note {{here}} |
1435 | }; |
1436 | }; |
1437 | constexpr E e1 = {{1}}; |
1438 | constexpr E e2 = e1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} |
1439 | |
1440 | struct F { |
1441 | union U { }; |
1442 | mutable U u; |
1443 | struct X { }; |
1444 | mutable X x; |
1445 | struct Y : X { X x; U u; }; |
1446 | mutable Y y; |
1447 | int n; |
1448 | }; |
1449 | // This is OK; we don't actually read any mutable state here. |
1450 | constexpr F f1 = {}; |
1451 | constexpr F f2 = f1; |
1452 | |
1453 | struct G { |
1454 | struct X {}; |
1455 | union U { X a; }; |
1456 | mutable U u; // expected-note {{here}} |
1457 | }; |
1458 | constexpr G g1 = {}; |
1459 | constexpr G g2 = g1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} |
1460 | constexpr G::U gu1 = {}; |
1461 | constexpr G::U gu2 = gu1; |
1462 | |
1463 | union H { |
1464 | mutable G::X gx; // expected-note {{here}} |
1465 | }; |
1466 | constexpr H h1 = {}; |
1467 | constexpr H h2 = h1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} |
1468 | } |
1469 | |
1470 | namespace Fold { |
1471 | |
1472 | // This macro forces its argument to be constant-folded, even if it's not |
1473 | // otherwise a constant expression. |
1474 | #define fold(x) (__builtin_constant_p(x) ? (x) : (x)) |
1475 | |
1476 | constexpr int n = (long)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}} |
1477 | constexpr int m = fold((long)(char*)123); // ok |
1478 | static_assert(m == 123, ""); |
1479 | |
1480 | #undef fold |
1481 | |
1482 | } |
1483 | |
1484 | namespace DR1454 { |
1485 | |
1486 | constexpr const int &f(const int &n) { return n; } |
1487 | constexpr int k1 = f(0); // ok |
1488 | |
1489 | struct Wrap { |
1490 | const int &value; |
1491 | }; |
1492 | constexpr const Wrap &g(const Wrap &w) { return w; } |
1493 | constexpr int k2 = g({0}).value; // ok |
1494 | |
1495 | // The temporary here has static storage duration, so we can bind a constexpr |
1496 | // reference to it. |
1497 | constexpr const int &i = 1; |
1498 | constexpr const int j = i; |
1499 | static_assert(j == 1, ""); |
1500 | |
1501 | // The temporary here is not const, so it can't be read outside the expression |
1502 | // in which it was created (per the C++14 rules, which we use to avoid a C++11 |
1503 | // defect). |
1504 | constexpr int &&k = 1; // expected-note {{temporary created here}} |
1505 | constexpr const int l = k; // expected-error {{constant expression}} expected-note {{read of temporary}} |
1506 | |
1507 | void f() { |
1508 | // The temporary here has automatic storage duration, so we can't bind a |
1509 | // constexpr reference to it. |
1510 | constexpr const int &i = 1; // expected-error {{constant expression}} expected-note 2{{temporary}} |
1511 | } |
1512 | |
1513 | } |
1514 | |
1515 | namespace RecursiveOpaqueExpr { |
1516 | template<typename Iter> |
1517 | constexpr auto LastNonzero(Iter p, Iter q) -> decltype(+*p) { |
1518 | return p != q ? (LastNonzero(p+1, q) ?: *p) : 0; // expected-warning {{GNU}} |
1519 | } |
1520 | |
1521 | constexpr int arr1[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 0 }; |
1522 | static_assert(LastNonzero(begin(arr1), end(arr1)) == 4, ""); |
1523 | |
1524 | constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 }; |
1525 | static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, ""); |
1526 | |
1527 | constexpr int arr3[] = { |
1528 | 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, |
1529 | 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, |
1530 | 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, |
1531 | 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, |
1532 | 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, |
1533 | 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, |
1534 | 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, |
1535 | 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
1536 | static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, ""); |
1537 | } |
1538 | |
1539 | namespace VLASizeof { |
1540 | |
1541 | void f(int k) { |
1542 | int arr[k]; // expected-warning {{C99}} |
1543 | constexpr int n = 1 + |
1544 | sizeof(arr) // expected-error {{constant expression}} |
1545 | * 3; |
1546 | } |
1547 | } |
1548 | |
1549 | namespace CompoundLiteral { |
1550 | // Matching GCC, file-scope array compound literals initialized by constants |
1551 | // are lifetime-extended. |
1552 | constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}} |
1553 | static_assert(*p == 3, ""); |
1554 | static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}} |
1555 | |
1556 | // Other kinds are not. |
1557 | struct X { int a[2]; }; |
1558 | constexpr int *n = (X){1, 2}.a; // expected-warning {{C99}} expected-warning {{temporary}} |
1559 | // expected-error@-1 {{constant expression}} |
1560 | // expected-note@-2 {{pointer to subobject of temporary}} |
1561 | // expected-note@-3 {{temporary created here}} |
1562 | |
1563 | void f() { |
1564 | static constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}} expected-warning {{temporary}} |
1565 | // expected-error@-1 {{constant expression}} |
1566 | // expected-note@-2 {{pointer to subobject of temporary}} |
1567 | // expected-note@-3 {{temporary created here}} |
1568 | static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}} |
1569 | } |
1570 | } |
1571 | |
1572 | namespace Vector { |
1573 | typedef int __attribute__((vector_size(16))) VI4; |
1574 | constexpr VI4 f(int n) { |
1575 | return VI4 { n * 3, n + 4, n - 5, n / 6 }; |
1576 | } |
1577 | constexpr auto v1 = f(10); |
1578 | |
1579 | typedef double __attribute__((vector_size(32))) VD4; |
1580 | constexpr VD4 g(int n) { |
1581 | return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 }; // expected-warning {{C99}} |
1582 | } |
1583 | constexpr auto v2 = g(4); |
1584 | } |
1585 | |
1586 | // PR12626, redux |
1587 | namespace InvalidClasses { |
1588 | void test0() { |
1589 | struct X; // expected-note {{forward declaration}} |
1590 | struct Y { bool b; X x; }; // expected-error {{field has incomplete type}} |
1591 | Y y; |
1592 | auto& b = y.b; |
1593 | } |
1594 | } |
1595 | |
1596 | namespace NamespaceAlias { |
1597 | constexpr int f() { |
1598 | namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++14 extension}} |
1599 | return &NS::f != nullptr; |
1600 | } |
1601 | } |
1602 | |
1603 | // Constructors can be implicitly constexpr, even for a non-literal type. |
1604 | namespace ImplicitConstexpr { |
1605 | struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}} |
1606 | struct R { constexpr R() noexcept; constexpr R(const R&) noexcept; constexpr R(R&&) noexcept; ~R() noexcept; }; |
1607 | struct S { R r; }; // expected-note 3{{here}} |
1608 | struct T { T(const T&) noexcept; T(T &&) noexcept; ~T() noexcept; }; |
1609 | struct U { T t; }; // expected-note 3{{here}} |
1610 | static_assert(!__is_literal_type(Q), ""); |
1611 | static_assert(!__is_literal_type(R), ""); |
1612 | static_assert(!__is_literal_type(S), ""); |
1613 | static_assert(!__is_literal_type(T), ""); |
1614 | static_assert(!__is_literal_type(U), ""); |
1615 | struct Test { |
1616 | friend Q::Q() noexcept; // expected-error {{follows constexpr}} |
1617 | friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}} |
1618 | friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}} |
1619 | friend S::S() noexcept; // expected-error {{follows constexpr}} |
1620 | friend S::S(S&&) noexcept; // expected-error {{follows constexpr}} |
1621 | friend S::S(const S&) noexcept; // expected-error {{follows constexpr}} |
1622 | friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}} |
1623 | friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}} |
1624 | friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}} |
1625 | }; |
1626 | } |
1627 | |
1628 | // Indirectly test that an implicit lvalue to xvalue conversion performed for |
1629 | // an NRVO move operation isn't implemented as CK_LValueToRValue. |
1630 | namespace PR12826 { |
1631 | struct Foo {}; |
1632 | constexpr Foo id(Foo x) { return x; } |
1633 | constexpr Foo res(id(Foo())); |
1634 | } |
1635 | |
1636 | namespace PR13273 { |
1637 | struct U { |
1638 | int t; |
1639 | U() = default; |
1640 | }; |
1641 | |
1642 | struct S : U { |
1643 | S() = default; |
1644 | }; |
1645 | |
1646 | // S's default constructor isn't constexpr, because U's default constructor |
1647 | // doesn't initialize 't', but it's trivial, so value-initialization doesn't |
1648 | // actually call it. |
1649 | static_assert(S{}.t == 0, ""); |
1650 | } |
1651 | |
1652 | namespace PR12670 { |
1653 | struct S { |
1654 | constexpr S(int a0) : m(a0) {} |
1655 | constexpr S() : m(6) {} |
1656 | int m; |
1657 | }; |
1658 | constexpr S x[3] = { {4}, 5 }; |
1659 | static_assert(x[0].m == 4, ""); |
1660 | static_assert(x[1].m == 5, ""); |
1661 | static_assert(x[2].m == 6, ""); |
1662 | } |
1663 | |
1664 | // Indirectly test that an implicit lvalue-to-rvalue conversion is performed |
1665 | // when a conditional operator has one argument of type void and where the other |
1666 | // is a glvalue of class type. |
1667 | namespace ConditionalLValToRVal { |
1668 | struct A { |
1669 | constexpr A(int a) : v(a) {} |
1670 | int v; |
1671 | }; |
1672 | |
1673 | constexpr A f(const A &a) { |
1674 | return a.v == 0 ? throw a : a; |
1675 | } |
1676 | |
1677 | constexpr A a(4); |
1678 | static_assert(f(a).v == 4, ""); |
1679 | } |
1680 | |
1681 | namespace TLS { |
1682 | __thread int n; |
1683 | int m; |
1684 | |
1685 | constexpr bool b = &n == &n; |
1686 | |
1687 | constexpr int *p = &n; // expected-error{{constexpr variable 'p' must be initialized by a constant expression}} |
1688 | |
1689 | constexpr int *f() { return &n; } |
1690 | constexpr int *q = f(); // expected-error{{constexpr variable 'q' must be initialized by a constant expression}} |
1691 | constexpr bool c = f() == f(); |
1692 | |
1693 | constexpr int *g() { return &m; } |
1694 | constexpr int *r = g(); |
1695 | } |
1696 | |
1697 | namespace Void { |
1698 | constexpr void f() { return; } // expected-error{{constexpr function's return type 'void' is not a literal type}} |
1699 | |
1700 | void assert_failed(const char *msg, const char *file, int line); // expected-note {{declared here}} |
1701 | #define ASSERT(expr) ((expr) ? static_cast<void>(0) : assert_failed(#expr, __FILE__, __LINE__)) |
1702 | template<typename T, size_t S> |
1703 | constexpr T get(T (&a)[S], size_t k) { |
1704 | return ASSERT(k > 0 && k < S), a[k]; // expected-note{{non-constexpr function 'assert_failed'}} |
1705 | } |
1706 | #undef ASSERT |
1707 | template int get(int (&a)[4], size_t); |
1708 | constexpr int arr[] = { 4, 1, 2, 3, 4 }; |
1709 | static_assert(get(arr, 1) == 1, ""); |
1710 | static_assert(get(arr, 4) == 4, ""); |
1711 | static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \ |
1712 | // expected-note{{in call to 'get(arr, 0)'}} |
1713 | } |
1714 | |
1715 | namespace std { struct type_info; } |
1716 | |
1717 | namespace TypeId { |
1718 | struct A { virtual ~A(); }; |
1719 | A f(); |
1720 | A &g(); |
1721 | constexpr auto &x = typeid(f()); |
1722 | constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \ |
1723 | // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}} \ |
1724 | // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} |
1725 | } |
1726 | |
1727 | namespace PR14203 { |
1728 | struct duration { |
1729 | constexpr duration() {} |
1730 | constexpr operator int() const { return 0; } |
1731 | }; |
1732 | template<typename T> void f() { |
1733 | // If we want to evaluate this at the point of the template definition, we |
1734 | // need to trigger the implicit definition of the move constructor at that |
1735 | // point. |
1736 | // FIXME: C++ does not permit us to implicitly define it at the appropriate |
1737 | // times, since it is only allowed to be implicitly defined when it is |
1738 | // odr-used. |
1739 | constexpr duration d = duration(); |
1740 | } |
1741 | // FIXME: It's unclear whether this is valid. On the one hand, we're not |
1742 | // allowed to generate a move constructor. On the other hand, if we did, |
1743 | // this would be a constant expression. For now, we generate a move |
1744 | // constructor here. |
1745 | int n = sizeof(short{duration(duration())}); |
1746 | } |
1747 | |
1748 | namespace ArrayEltInit { |
1749 | struct A { |
1750 | constexpr A() : p(&p) {} |
1751 | void *p; |
1752 | }; |
1753 | constexpr A a[10]; |
1754 | static_assert(a[0].p == &a[0].p, ""); |
1755 | static_assert(a[9].p == &a[9].p, ""); |
1756 | static_assert(a[0].p != &a[9].p, ""); |
1757 | static_assert(a[9].p != &a[0].p, ""); |
1758 | |
1759 | constexpr A b[10] = {}; |
1760 | static_assert(b[0].p == &b[0].p, ""); |
1761 | static_assert(b[9].p == &b[9].p, ""); |
1762 | static_assert(b[0].p != &b[9].p, ""); |
1763 | static_assert(b[9].p != &b[0].p, ""); |
1764 | } |
1765 | |
1766 | namespace PR15884 { |
1767 | struct S {}; |
1768 | constexpr S f() { return {}; } |
1769 | constexpr S *p = &f(); |
1770 | // expected-error@-1 {{taking the address of a temporary}} |
1771 | // expected-error@-2 {{constexpr variable 'p' must be initialized by a constant expression}} |
1772 | // expected-note@-3 {{pointer to temporary is not a constant expression}} |
1773 | // expected-note@-4 {{temporary created here}} |
1774 | } |
1775 | |
1776 | namespace AfterError { |
1777 | // FIXME: Suppress the 'no return statements' diagnostic if the body is invalid. |
1778 | constexpr int error() { // expected-error {{no return statement}} |
1779 | return foobar; // expected-error {{undeclared identifier}} |
1780 | } |
1781 | constexpr int k = error(); |
1782 | } |
1783 | |
1784 | namespace std { |
1785 | typedef decltype(sizeof(int)) size_t; |
1786 | |
1787 | template <class _E> |
1788 | class initializer_list |
1789 | { |
1790 | const _E* __begin_; |
1791 | size_t __size_; |
1792 | |
1793 | constexpr initializer_list(const _E* __b, size_t __s) |
1794 | : __begin_(__b), |
1795 | __size_(__s) |
1796 | {} |
1797 | |
1798 | public: |
1799 | typedef _E value_type; |
1800 | typedef const _E& reference; |
1801 | typedef const _E& const_reference; |
1802 | typedef size_t size_type; |
1803 | |
1804 | typedef const _E* iterator; |
1805 | typedef const _E* const_iterator; |
1806 | |
1807 | constexpr initializer_list() : __begin_(nullptr), __size_(0) {} |
1808 | |
1809 | constexpr size_t size() const {return __size_;} |
1810 | constexpr const _E* begin() const {return __begin_;} |
1811 | constexpr const _E* end() const {return __begin_ + __size_;} |
1812 | }; |
1813 | } |
1814 | |
1815 | namespace InitializerList { |
1816 | constexpr int sum(const int *b, const int *e) { |
1817 | return b != e ? *b + sum(b+1, e) : 0; |
1818 | } |
1819 | constexpr int sum(std::initializer_list<int> ints) { |
1820 | return sum(ints.begin(), ints.end()); |
1821 | } |
1822 | static_assert(sum({1, 2, 3, 4, 5}) == 15, ""); |
1823 | |
1824 | static_assert(*std::initializer_list<int>{1, 2, 3}.begin() == 1, ""); |
1825 | static_assert(std::initializer_list<int>{1, 2, 3}.begin()[2] == 3, ""); |
1826 | } |
1827 | |
1828 | namespace StmtExpr { |
1829 | struct A { int k; }; |
1830 | void f() { |
1831 | static_assert(({ const int x = 5; x * 3; }) == 15, ""); // expected-warning {{extension}} |
1832 | constexpr auto a = ({ A(); }); // expected-warning {{extension}} |
1833 | } |
1834 | constexpr int g(int k) { |
1835 | return ({ // expected-warning {{extension}} |
1836 | const int x = k; |
1837 | x * x; |
1838 | }); |
1839 | } |
1840 | static_assert(g(123) == 15129, ""); |
1841 | constexpr int h() { // expected-error {{never produces a constant}} |
1842 | return ({ // expected-warning {{extension}} |
1843 | return 0; // expected-note {{not supported}} |
1844 | 1; |
1845 | }); |
1846 | } |
1847 | } |
1848 | |
1849 | namespace VirtualFromBase { |
1850 | struct S1 { |
1851 | virtual int f() const; |
1852 | }; |
1853 | struct S2 { |
1854 | virtual int f(); |
1855 | }; |
1856 | template <typename T> struct X : T { |
1857 | constexpr X() {} |
1858 | double d = 0.0; |
1859 | constexpr int f() { return sizeof(T); } // expected-warning {{will not be implicitly 'const' in C++14}} |
1860 | }; |
1861 | |
1862 | // Virtual f(), not OK. |
1863 | constexpr X<X<S1>> xxs1; |
1864 | constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1); |
1865 | static_assert(p->f() == sizeof(X<S1>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}} |
1866 | |
1867 | // Non-virtual f(), OK. |
1868 | constexpr X<X<S2>> xxs2; |
1869 | constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2); |
1870 | static_assert(q->f() == sizeof(S2), ""); |
1871 | } |
1872 | |
1873 | namespace ConstexprConstructorRecovery { |
1874 | class X { |
1875 | public: |
1876 | enum E : short { |
1877 | headers = 0x1, |
1878 | middlefile = 0x2, |
1879 | choices = 0x4 |
1880 | }; |
1881 | constexpr X() noexcept {}; |
1882 | protected: |
1883 | E val{0}; // expected-error {{cannot initialize a member subobject of type 'ConstexprConstructorRecovery::X::E' with an rvalue of type 'int'}} |
1884 | }; |
1885 | constexpr X x{}; |
1886 | } |
1887 | |
1888 | namespace Lifetime { |
1889 | void f() { |
1890 | constexpr int &n = n; // expected-error {{constant expression}} expected-note {{use of reference outside its lifetime}} expected-warning {{not yet bound to a value}} |
1891 | constexpr int m = m; // expected-error {{constant expression}} expected-note {{read of object outside its lifetime}} |
1892 | } |
1893 | |
1894 | constexpr int &get(int &&n) { return n; } |
1895 | constexpr int &&get_rv(int &&n) { return static_cast<int&&>(n); } |
1896 | struct S { |
1897 | int &&r; |
1898 | int &s; |
1899 | int t; |
1900 | constexpr S() : r(get_rv(0)), s(get(0)), t(r) {} // expected-note {{read of object outside its lifetime}} |
1901 | constexpr S(int) : r(get_rv(0)), s(get(0)), t(s) {} // expected-note {{read of object outside its lifetime}} |
1902 | }; |
1903 | constexpr int k1 = S().t; // expected-error {{constant expression}} expected-note {{in call}} |
1904 | constexpr int k2 = S(0).t; // expected-error {{constant expression}} expected-note {{in call}} |
1905 | } |
1906 | |
1907 | namespace Bitfields { |
1908 | struct A { |
1909 | bool b : 1; |
1910 | unsigned u : 5; |
1911 | int n : 5; |
1912 | bool b2 : 3; |
1913 | unsigned u2 : 74; // expected-warning {{exceeds the width of its type}} |
1914 | int n2 : 81; // expected-warning {{exceeds the width of its type}} |
1915 | }; |
1916 | |
1917 | constexpr A a = { false, 33, 31, false, 0xffffffff, 0x7fffffff }; // expected-warning 2{{truncation}} |
1918 | static_assert(a.b == 0 && a.u == 1 && a.n == -1 && a.b2 == 0 && |
1919 | a.u2 + 1 == 0 && a.n2 == 0x7fffffff, |
1920 | "bad truncation of bitfield values"); |
1921 | |
1922 | struct B { |
1923 | int n : 3; |
1924 | constexpr B(int k) : n(k) {} |
1925 | }; |
1926 | static_assert(B(3).n == 3, ""); |
1927 | static_assert(B(4).n == -4, ""); |
1928 | static_assert(B(7).n == -1, ""); |
1929 | static_assert(B(8).n == 0, ""); |
1930 | static_assert(B(-1).n == -1, ""); |
1931 | static_assert(B(-8889).n == -1, ""); |
1932 | |
1933 | namespace PR16755 { |
1934 | struct X { |
1935 | int x : 1; |
1936 | constexpr static int f(int x) { |
1937 | return X{x}.x; |
1938 | } |
1939 | }; |
1940 | static_assert(X::f(3) == -1, "3 should truncate to -1"); |
1941 | } |
1942 | |
1943 | struct HasUnnamedBitfield { |
1944 | unsigned a; |
1945 | unsigned : 20; |
1946 | unsigned b; |
1947 | |
1948 | constexpr HasUnnamedBitfield() : a(), b() {} |
1949 | constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {} |
1950 | }; |
1951 | |
1952 | void testUnnamedBitfield() { |
1953 | const HasUnnamedBitfield zero{}; |
1954 | int a = 1 / zero.b; // expected-warning {{division by zero is undefined}} |
1955 | const HasUnnamedBitfield oneZero{1, 0}; |
1956 | int b = 1 / oneZero.b; // expected-warning {{division by zero is undefined}} |
1957 | } |
1958 | } |
1959 | |
1960 | namespace ZeroSizeTypes { |
1961 | constexpr int (*p1)[0] = 0, (*p2)[0] = 0; |
1962 | constexpr int k = p2 - p1; |
1963 | // expected-error@-1 {{constexpr variable 'k' must be initialized by a constant expression}} |
1964 | // expected-note@-2 {{subtraction of pointers to type 'int [0]' of zero size}} |
1965 | |
1966 | int arr[5][0]; |
1967 | constexpr int f() { // expected-error {{never produces a constant expression}} |
1968 | return &arr[3] - &arr[0]; // expected-note {{subtraction of pointers to type 'int [0]' of zero size}} |
1969 | } |
1970 | } |
1971 | |
1972 | namespace BadDefaultInit { |
1973 | template<int N> struct X { static const int n = N; }; |
1974 | |
1975 | struct A { // expected-error {{default member initializer for 'k' needed within definition of enclosing class}} |
1976 | int k = // expected-note {{default member initializer declared here}} |
1977 | X<A().k>::n; // expected-note {{in evaluation of exception specification for 'BadDefaultInit::A::A' needed here}} |
1978 | }; |
1979 | |
1980 | // FIXME: The "constexpr constructor must initialize all members" diagnostic |
1981 | // here is bogus (we discard the k(k) initializer because the parameter 'k' |
1982 | // has been marked invalid). |
1983 | struct B { // expected-note 2{{candidate}} |
1984 | constexpr B( // expected-error {{must initialize all members}} expected-note {{candidate}} |
1985 | int k = X<B().k>::n) : // expected-error {{no matching constructor}} |
1986 | k(k) {} |
1987 | int k; // expected-note {{not initialized}} |
1988 | }; |
1989 | } |
1990 | |
1991 | namespace NeverConstantTwoWays { |
1992 | // If we see something non-constant but foldable followed by something |
1993 | // non-constant and not foldable, we want the first diagnostic, not the |
1994 | // second. |
1995 | constexpr int f(int n) { // expected-error {{never produces a constant expression}} |
1996 | return (int *)(long)&n == &n ? // expected-note {{reinterpret_cast}} |
1997 | 1 / 0 : // expected-warning {{division by zero}} |
1998 | 0; |
1999 | } |
2000 | |
2001 | constexpr int n = // expected-error {{must be initialized by a constant expression}} |
2002 | (int *)(long)&n == &n ? // expected-note {{reinterpret_cast}} |
2003 | 1 / 0 : |
2004 | 0; |
2005 | } |
2006 | |
2007 | namespace PR17800 { |
2008 | struct A { |
2009 | constexpr int operator()() const { return 0; } |
2010 | }; |
2011 | template <typename ...T> constexpr int sink(T ...) { |
2012 | return 0; |
2013 | } |
2014 | template <int ...N> constexpr int run() { |
2015 | return sink(A()() + N ...); |
2016 | } |
2017 | constexpr int k = run<1, 2, 3>(); |
2018 | } |
2019 | |
2020 | namespace BuiltinStrlen { |
2021 | constexpr const char *a = "foo\0quux"; |
2022 | constexpr char b[] = "foo\0quux"; |
2023 | constexpr int f() { return 'u'; } |
2024 | constexpr char c[] = { 'f', 'o', 'o', 0, 'q', f(), 'u', 'x', 0 }; |
2025 | |
2026 | static_assert(__builtin_strlen("foo") == 3, ""); |
2027 | static_assert(__builtin_strlen("foo\0quux") == 3, ""); |
2028 | static_assert(__builtin_strlen("foo\0quux" + 4) == 4, ""); |
2029 | |
2030 | constexpr bool check(const char *p) { |
2031 | return __builtin_strlen(p) == 3 && |
2032 | __builtin_strlen(p + 1) == 2 && |
2033 | __builtin_strlen(p + 2) == 1 && |
2034 | __builtin_strlen(p + 3) == 0 && |
2035 | __builtin_strlen(p + 4) == 4 && |
2036 | __builtin_strlen(p + 5) == 3 && |
2037 | __builtin_strlen(p + 6) == 2 && |
2038 | __builtin_strlen(p + 7) == 1 && |
2039 | __builtin_strlen(p + 8) == 0; |
2040 | } |
2041 | |
2042 | static_assert(check(a), ""); |
2043 | static_assert(check(b), ""); |
2044 | static_assert(check(c), ""); |
2045 | |
2046 | constexpr int over1 = __builtin_strlen(a + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}} |
2047 | constexpr int over2 = __builtin_strlen(b + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}} |
2048 | constexpr int over3 = __builtin_strlen(c + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}} |
2049 | |
2050 | constexpr int under1 = __builtin_strlen(a - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} |
2051 | constexpr int under2 = __builtin_strlen(b - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} |
2052 | constexpr int under3 = __builtin_strlen(c - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} |
2053 | |
2054 | // FIXME: The diagnostic here could be better. |
2055 | constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator. |
2056 | constexpr int bad = __builtin_strlen(d); // expected-error {{constant expression}} expected-note {{one-past-the-end}} |
2057 | } |
2058 | |
2059 | namespace PR19010 { |
2060 | struct Empty {}; |
2061 | struct Empty2 : Empty {}; |
2062 | struct Test : Empty2 { |
2063 | constexpr Test() {} |
2064 | Empty2 array[2]; |
2065 | }; |
2066 | void test() { constexpr Test t; } |
2067 | } |
2068 | |
2069 | void PR21327(int a, int b) { |
2070 | static_assert(&a + 1 != &b, ""); // expected-error {{constant expression}} |
2071 | } |
2072 | |
2073 | namespace EmptyClass { |
2074 | struct E1 {} e1; |
2075 | union E2 {} e2; // expected-note {{here}} |
2076 | struct E3 : E1 {} e3; |
2077 | |
2078 | // The defaulted copy constructor for an empty class does not read any |
2079 | // members. The defaulted copy constructor for an empty union reads the |
2080 | // object representation. |
2081 | constexpr E1 e1b(e1); |
2082 | constexpr E2 e2b(e2); // expected-error {{constant expression}} expected-note{{read of non-const}} expected-note {{in call}} |
2083 | constexpr E3 e3b(e3); |
2084 | } |
2085 | |
2086 | namespace PR21786 { |
2087 | extern void (*start[])(); |
2088 | extern void (*end[])(); |
2089 | static_assert(&start != &end, ""); // expected-error {{constant expression}} |
2090 | static_assert(&start != nullptr, ""); |
2091 | |
2092 | struct Foo; |
2093 | struct Bar { |
2094 | static const Foo x; |
2095 | static const Foo y; |
2096 | }; |
2097 | static_assert(&Bar::x != nullptr, ""); |
2098 | static_assert(&Bar::x != &Bar::y, ""); |
2099 | } |
2100 | |
2101 | namespace PR21859 { |
2102 | constexpr int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}} |
2103 | constexpr int Var = Fun(); |
2104 | } |
2105 | |
2106 | struct InvalidRedef { |
2107 | int f; // expected-note{{previous definition is here}} |
2108 | constexpr int f(void); // expected-error{{redefinition of 'f'}} expected-warning{{will not be implicitly 'const'}} |
2109 | }; |
2110 | |
2111 | namespace PR17938 { |
2112 | template <typename T> constexpr T const &f(T const &x) { return x; } |
2113 | |
2114 | struct X {}; |
2115 | struct Y : X {}; |
2116 | struct Z : Y { constexpr Z() {} }; |
2117 | |
2118 | static constexpr auto z = f(Z()); |
2119 | } |
2120 | |
2121 | namespace PR24597 { |
2122 | struct A { |
2123 | int x, *p; |
2124 | constexpr A() : x(0), p(&x) {} |
2125 | constexpr A(const A &a) : x(a.x), p(&x) {} |
2126 | }; |
2127 | constexpr A f() { return A(); } |
2128 | constexpr A g() { return f(); } |
2129 | constexpr int a = *f().p; |
2130 | constexpr int b = *g().p; |
2131 | } |
2132 | |
2133 | namespace IncompleteClass { |
2134 | struct XX { |
2135 | static constexpr int f(XX*) { return 1; } // expected-note {{here}} |
2136 | friend constexpr int g(XX*) { return 2; } // expected-note {{here}} |
2137 | |
2138 | static constexpr int i = f(static_cast<XX*>(nullptr)); // expected-error {{constexpr variable 'i' must be initialized by a constant expression}} expected-note {{undefined function 'f' cannot be used in a constant expression}} |
2139 | static constexpr int j = g(static_cast<XX*>(nullptr)); // expected-error {{constexpr variable 'j' must be initialized by a constant expression}} expected-note {{undefined function 'g' cannot be used in a constant expression}} |
2140 | }; |
2141 | } |
2142 | |
2143 | namespace InheritedCtor { |
2144 | struct A { constexpr A(int) {} }; |
2145 | |
2146 | struct B : A { int n; using A::A; }; // expected-note {{here}} |
2147 | constexpr B b(0); // expected-error {{constant expression}} expected-note {{derived class}} |
2148 | |
2149 | struct C : A { using A::A; struct { union { int n, m = 0; }; union { int a = 0; }; int k = 0; }; struct {}; union {}; }; // expected-warning 4{{extension}} |
2150 | constexpr C c(0); |
2151 | |
2152 | struct D : A { |
2153 | using A::A; // expected-note {{here}} |
2154 | struct { // expected-warning {{extension}} |
2155 | union { // expected-warning {{extension}} |
2156 | int n; |
2157 | }; |
2158 | }; |
2159 | }; |
2160 | constexpr D d(0); // expected-error {{constant expression}} expected-note {{derived class}} |
2161 | |
2162 | struct E : virtual A { using A::A; }; // expected-note {{here}} |
2163 | // We wrap a function around this to avoid implicit zero-initialization |
2164 | // happening first; the zero-initialization step would produce the same |
2165 | // error and defeat the point of this test. |
2166 | void f() { |
2167 | constexpr E e(0); // expected-error {{constant expression}} expected-note {{derived class}} |
2168 | } |
2169 | // FIXME: This produces a note with no source location. |
2170 | //constexpr E e(0); |
2171 | |
2172 | struct W { constexpr W(int n) : w(n) {} int w; }; |
2173 | struct X : W { using W::W; int x = 2; }; |
2174 | struct Y : X { using X::X; int y = 3; }; |
2175 | struct Z : Y { using Y::Y; int z = 4; }; |
2176 | constexpr Z z(1); |
2177 | static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, ""); |
2178 | } |
2179 | |
2180 | |
2181 | namespace PR28366 { |
2182 | namespace ns1 { |
2183 | |
2184 | void f(char c) { //expected-note2{{declared here}} |
2185 | struct X { |
2186 | static constexpr char f() { //expected-error{{never produces a constant expression}} |
2187 | return c; //expected-error{{reference to local}} expected-note{{non-const variable}} |
2188 | } |
2189 | }; |
2190 | int I = X::f(); |
2191 | } |
2192 | |
2193 | void g() { |
2194 | const int c = 'c'; |
2195 | static const int d = 'd'; |
2196 | struct X { |
2197 | static constexpr int f() { |
2198 | return c + d; |
2199 | } |
2200 | }; |
2201 | static_assert(X::f() == 'c' + 'd',""); |
2202 | } |
2203 | |
2204 | |
2205 | } // end ns1 |
2206 | |
2207 | } //end ns PR28366 |
2208 | |
2209 | namespace PointerArithmeticOverflow { |
2210 | int n; |
2211 | int a[1]; |
2212 | constexpr int *b = &n + 1 + (long)-1; |
2213 | constexpr int *c = &n + 1 + (unsigned long)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element 1844}} |
2214 | constexpr int *d = &n + 1 - (unsigned long)1; |
2215 | constexpr int *e = a + 1 + (long)-1; |
2216 | constexpr int *f = a + 1 + (unsigned long)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element 1844}} |
2217 | constexpr int *g = a + 1 - (unsigned long)1; |
2218 | |
2219 | constexpr int *p = (&n + 1) + (unsigned __int128)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element 3402}} |
2220 | constexpr int *q = (&n + 1) - (unsigned __int128)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element -3402}} |
2221 | constexpr int *r = &(&n + 1)[(unsigned __int128)-1]; // expected-error {{constant expression}} expected-note {{cannot refer to element 3402}} |
2222 | } |
2223 | |
2224 | namespace PR40430 { |
2225 | struct S { |
2226 | char c[10] = "asdf"; |
2227 | constexpr char foo() const { return c[3]; } |
2228 | }; |
2229 | static_assert(S().foo() == 'f', ""); |
2230 | } |
2231 | |