Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / AST / Interp / literals.cpp
blobba24955d14503bebc01a8a9b047fb7b716fe35c8
1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -Wno-vla -fms-extensions -std=c++11 -verify %s
2 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -Wno-vla -fms-extensions -std=c++20 -verify %s
3 // RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-vla -verify=ref %s
4 // RUN: %clang_cc1 -std=c++20 -fms-extensions -Wno-vla -verify=ref %s
6 #define INT_MIN (~__INT_MAX__)
7 #define INT_MAX __INT_MAX__
9 typedef __INTPTR_TYPE__ intptr_t;
12 static_assert(true, "");
13 static_assert(false, ""); // expected-error{{failed}} ref-error{{failed}}
14 static_assert(nullptr == nullptr, "");
15 static_assert(__null == __null, "");
16 static_assert(1 == 1, "");
17 static_assert(1 == 3, ""); // expected-error{{failed}} ref-error{{failed}}
19 constexpr void* v = nullptr;
20 static_assert(__null == v, "");
22 constexpr int number = 10;
23 static_assert(number == 10, "");
24 static_assert(number != 10, ""); // expected-error{{failed}} \
25 // ref-error{{failed}} \
26 // expected-note{{evaluates to}} \
27 // ref-note{{evaluates to}}
29 constexpr bool b = number;
30 static_assert(b, "");
31 constexpr int one = true;
32 static_assert(one == 1, "");
34 constexpr bool b2 = bool();
35 static_assert(!b2, "");
37 namespace ScalarTypes {
38 constexpr int ScalarInitInt = int();
39 static_assert(ScalarInitInt == 0, "");
40 constexpr float ScalarInitFloat = float();
41 static_assert(ScalarInitFloat == 0.0f, "");
43 static_assert(decltype(nullptr)() == nullptr, "");
45 template<typename T>
46 constexpr T getScalar() { return T(); }
48 static_assert(getScalar<const int>() == 0, "");
49 static_assert(getScalar<const double>() == 0.0, "");
51 static_assert(getScalar<void*>() == nullptr, "");
52 static_assert(getScalar<void(*)(void)>() == nullptr, "");
54 enum E {
55 First = 0,
57 static_assert(getScalar<E>() == First, "");
58 /// FIXME: Member pointers.
60 #if __cplusplus >= 201402L
61 constexpr void Void(int n) {
62 void(n + 1);
63 void();
65 constexpr int void_test = (Void(0), 1);
66 static_assert(void_test == 1, "");
67 #endif
70 namespace IntegralCasts {
71 constexpr int i = 12;
72 constexpr unsigned int ui = i;
73 static_assert(ui == 12, "");
74 constexpr unsigned int ub = !false;
75 static_assert(ub == 1, "");
77 constexpr int si = ui;
78 static_assert(si == 12, "");
79 constexpr int sb = true;
80 static_assert(sb == 1, "");
82 constexpr int zero = 0;
83 constexpr unsigned int uzero = 0;
84 constexpr bool bs = i;
85 static_assert(bs, "");
86 constexpr bool bu = ui;
87 static_assert(bu, "");
88 constexpr bool ns = zero;
89 static_assert(!ns, "");
90 constexpr bool nu = uzero;
91 static_assert(!nu, "");
94 constexpr int UninitI; // expected-error {{must be initialized by a constant expression}} \
95 // ref-error {{must be initialized by a constant expression}}
96 constexpr int *UninitPtr; // expected-error {{must be initialized by a constant expression}} \
97 // ref-error {{must be initialized by a constant expression}}
99 constexpr bool getTrue() { return true; }
100 constexpr bool getFalse() { return false; }
101 constexpr void* getNull() { return nullptr; }
103 constexpr int neg(int m) { return -m; }
104 constexpr bool inv(bool b) { return !b; }
106 static_assert(12, "");
107 static_assert(12 == -(-(12)), "");
108 static_assert(!false, "");
109 static_assert(!!true, "");
110 static_assert(!!true == !false, "");
111 static_assert(true == 1, "");
112 static_assert(false == 0, "");
113 static_assert(!5 == false, "");
114 static_assert(!0, "");
115 static_assert(-true, "");
116 static_assert(-false, ""); //expected-error{{failed}} ref-error{{failed}}
118 static_assert(~0 == -1, "");
119 static_assert(~1 == -2, "");
120 static_assert(~-1 == 0, "");
121 static_assert(~255 == -256, "");
122 static_assert(~INT_MIN == INT_MAX, "");
123 static_assert(~INT_MAX == INT_MIN, "");
125 static_assert(-(1 << 31), ""); // expected-error {{not an integral constant expression}} \
126 // expected-note {{outside the range of representable values}} \
127 // ref-error {{not an integral constant expression}} \
128 // ref-note {{outside the range of representable values}} \
130 namespace PrimitiveEmptyInitList {
131 constexpr int a = {};
132 static_assert(a == 0, "");
133 constexpr bool b = {};
134 static_assert(!b, "");
135 constexpr double d = {};
136 static_assert(d == 0.0, "");
140 enum E {};
141 constexpr E e = static_cast<E>(0);
142 static_assert(~e == -1, "");
145 constexpr int m = 10;
146 constexpr const int *p = &m;
147 static_assert(p != nullptr, "");
148 static_assert(*p == 10, "");
150 constexpr const int* getIntPointer() {
151 return &m;
153 static_assert(getIntPointer() == &m, "");
154 static_assert(*getIntPointer() == 10, "");
156 constexpr int gimme(int k) {
157 return k;
159 static_assert(gimme(5) == 5, "");
161 namespace PointerToBool {
163 constexpr void *N = nullptr;
164 constexpr bool B = N;
165 static_assert(!B, "");
166 static_assert(!N, "");
168 constexpr float F = 1.0;
169 constexpr const float *FP = &F;
170 static_assert(FP, "");
171 static_assert(!!FP, "");
174 namespace PointerComparison {
176 struct S { int a, b; } s;
177 constexpr void *null = 0;
178 constexpr void *pv = (void*)&s.a;
179 constexpr void *qv = (void*)&s.b;
180 constexpr bool v1 = null < (int*)0;
181 constexpr bool v2 = null < pv; // expected-error {{must be initialized by a constant expression}} \
182 // expected-note {{comparison between 'nullptr' and '&s.a' has unspecified value}} \
183 // ref-error {{must be initialized by a constant expression}} \
184 // ref-note {{comparison between 'nullptr' and '&s.a' has unspecified value}} \
186 constexpr bool v3 = null == pv; // ok
187 constexpr bool v4 = qv == pv; // ok
189 /// FIXME: These two are rejected by the current interpreter, but
190 /// accepted by GCC.
191 constexpr bool v5 = qv >= pv; // ref-error {{constant expression}} \
192 // ref-note {{unequal pointers to void}}
193 constexpr bool v8 = qv > (void*)&s.a; // ref-error {{constant expression}} \
194 // ref-note {{unequal pointers to void}}
195 constexpr bool v6 = qv > null; // expected-error {{must be initialized by a constant expression}} \
196 // expected-note {{comparison between '&s.b' and 'nullptr' has unspecified value}} \
197 // ref-error {{must be initialized by a constant expression}} \
198 // ref-note {{comparison between '&s.b' and 'nullptr' has unspecified value}}
200 constexpr bool v7 = qv <= (void*)&s.b; // ok
203 namespace SizeOf {
204 constexpr int soint = sizeof(int);
205 constexpr int souint = sizeof(unsigned int);
206 static_assert(soint == souint, "");
208 static_assert(sizeof(&soint) == sizeof(void*), "");
209 static_assert(sizeof(&soint) == sizeof(nullptr), "");
211 static_assert(sizeof(long) == sizeof(unsigned long), "");
212 static_assert(sizeof(char) == sizeof(unsigned char), "");
214 constexpr int N = 4;
215 constexpr int arr[N] = {1,2,3,4};
216 static_assert(sizeof(arr) == N * sizeof(int), "");
217 static_assert(sizeof(arr) == N * sizeof(arr[0]), "");
219 constexpr bool arrB[N] = {true, true, true, true};
220 static_assert(sizeof(arrB) == N * sizeof(bool), "");
222 static_assert(sizeof(bool) == 1, "");
223 static_assert(sizeof(char) == 1, "");
225 constexpr int F = sizeof(void); // expected-error{{incomplete type 'void'}} \
226 // ref-error{{incomplete type 'void'}}
228 constexpr int F2 = sizeof(gimme); // expected-error{{to a function type}} \
229 // ref-error{{to a function type}}
232 struct S {
233 void func();
235 constexpr void (S::*Func)() = &S::func;
236 static_assert(sizeof(Func) == sizeof(&S::func), "");
239 void func() {
240 int n = 12;
241 constexpr int oofda = sizeof(int[n++]); // expected-error {{must be initialized by a constant expression}} \
242 // ref-error {{must be initialized by a constant expression}}
245 #if __cplusplus >= 201402L
246 constexpr int IgnoredRejected() { // ref-error {{never produces a constant expression}}
247 int n = 0;
248 sizeof(int[n++]); // expected-warning {{expression result unused}} \
249 // ref-warning {{expression result unused}} \
250 // ref-note 2{{subexpression not valid in a constant expression}}
251 return n;
253 /// FIXME: This is rejected because the parameter so sizeof() is not constant.
254 /// produce a proper diagnostic.
255 static_assert(IgnoredRejected() == 0, ""); // expected-error {{not an integral constant expression}} \
256 // ref-error {{not an integral constant expression}} \
257 // ref-note {{in call to 'IgnoredRejected()'}}
258 #endif
261 #if __cplusplus >= 202002L
262 /// FIXME: The following code should be accepted.
263 consteval int foo(int n) { // ref-error {{consteval function never produces a constant expression}}
264 return sizeof(int[n]); // ref-note 3{{not valid in a constant expression}} \
265 // expected-note {{not valid in a constant expression}}
267 constinit int var = foo(5); // ref-error {{not a constant expression}} \
268 // ref-note 2{{in call to}} \
269 // ref-error {{does not have a constant initializer}} \
270 // ref-note {{required by 'constinit' specifier}} \
271 // expected-error {{is not a constant expression}} \
272 // expected-note {{in call to}} \
273 // expected-error {{does not have a constant initializer}} \
274 // expected-note {{required by 'constinit' specifier}} \
276 #endif
279 namespace rem {
280 static_assert(2 % 2 == 0, "");
281 static_assert(2 % 1 == 0, "");
282 static_assert(-3 % 4 == -3, "");
283 static_assert(4 % -2 == 0, "");
284 static_assert(-3 % -4 == -3, "");
286 constexpr int zero() { return 0; }
287 static_assert(10 % zero() == 20, ""); // ref-error {{not an integral constant expression}} \
288 // ref-note {{division by zero}} \
289 // expected-error {{not an integral constant expression}} \
290 // expected-note {{division by zero}}
293 static_assert(true % true == 0, "");
294 static_assert(false % true == 0, "");
295 static_assert(true % false == 10, ""); // ref-error {{not an integral constant expression}} \
296 // ref-note {{division by zero}} \
297 // expected-error {{not an integral constant expression}} \
298 // expected-note {{division by zero}}
299 constexpr int x = INT_MIN % - 1; // ref-error {{must be initialized by a constant expression}} \
300 // ref-note {{value 2147483648 is outside the range}} \
301 // expected-error {{must be initialized by a constant expression}} \
302 // expected-note {{value 2147483648 is outside the range}} \
306 namespace div {
307 constexpr int zero() { return 0; }
308 static_assert(12 / 3 == 4, "");
309 static_assert(12 / zero() == 12, ""); // ref-error {{not an integral constant expression}} \
310 // ref-note {{division by zero}} \
311 // expected-error {{not an integral constant expression}} \
312 // expected-note {{division by zero}}
313 static_assert(12 / -3 == -4, "");
314 static_assert(-12 / 3 == -4, "");
317 constexpr int LHS = 12;
318 constexpr long unsigned RHS = 3;
319 static_assert(LHS / RHS == 4, "");
321 constexpr int x = INT_MIN / - 1; // ref-error {{must be initialized by a constant expression}} \
322 // ref-note {{value 2147483648 is outside the range}} \
323 // expected-error {{must be initialized by a constant expression}} \
324 // expected-note {{value 2147483648 is outside the range}} \
328 namespace cond {
329 constexpr bool isEven(int n) {
330 return n % 2 == 0 ? true : false;
332 static_assert(isEven(2), "");
333 static_assert(!isEven(3), "");
334 static_assert(isEven(100), "");
336 constexpr int M = 5 ? 10 : 20;
337 static_assert(M == 10, "");
339 static_assert(5 ? 13 : 16 == 13, "");
340 static_assert(0 ? 13 : 16 == 16, "");
342 static_assert(number ?: -15 == number, "");
343 static_assert(0 ?: 100 == 100 , "");
345 #if __cplusplus >= 201402L
346 constexpr int N = 20;
347 constexpr int foo() {
348 int m = N > 0 ? 5 : 10;
350 return m == 5 ? isEven(m) : true;
352 static_assert(foo() == false, "");
354 constexpr int dontCallMe(unsigned m) {
355 if (m == 0) return 0;
356 return dontCallMe(m - 2);
359 // Can't call this because it will run into infinite recursion.
360 constexpr int assertNotReached() {
361 return dontCallMe(3);
364 constexpr int testCond() {
365 return true ? 5 : assertNotReached();
368 constexpr int testCond2() {
369 return false ? assertNotReached() : 10;
372 static_assert(testCond() == 5, "");
373 static_assert(testCond2() == 10, "");
375 #endif
379 namespace band {
380 static_assert((10 & 1) == 0, "");
381 static_assert((10 & 10) == 10, "");
383 static_assert((1337 & -1) == 1337, "");
384 static_assert((0 & gimme(12)) == 0, "");
387 namespace bitOr {
388 static_assert((10 | 1) == 11, "");
389 static_assert((10 | 10) == 10, "");
391 static_assert((1337 | -1) == -1, "");
392 static_assert((0 | gimme(12)) == 12, "");
393 static_assert((12 | true) == 13, "");
396 namespace bitXor {
397 #pragma clang diagnostic push
398 #pragma clang diagnostic ignored "-Wxor-used-as-pow"
399 static_assert((10 ^ 1) == 11, "");
400 static_assert((10 ^ 10) == 0, "");
402 enum {
403 ONE = 1,
406 static_assert((1337 ^ -1) == -1338, "");
407 static_assert((0 | gimme(12)) == 12, "");
408 static_assert((12 ^ true) == 13, "");
409 static_assert((12 ^ ONE) == 13, "");
410 #pragma clang diagnostic pop
413 #if __cplusplus >= 201402L
414 constexpr bool IgnoredUnary() {
415 bool bo = true;
416 !bo; // expected-warning {{expression result unused}} \
417 // ref-warning {{expression result unused}}
418 return bo;
420 static_assert(IgnoredUnary(), "");
421 #endif
423 namespace strings {
424 constexpr const char *S = "abc";
425 static_assert(S[0] == 97, "");
426 static_assert(S[1] == 98, "");
427 static_assert(S[2] == 99, "");
428 static_assert(S[3] == 0, "");
430 static_assert("foobar"[2] == 'o', "");
431 static_assert(2["foobar"] == 'o', "");
433 constexpr const wchar_t *wide = L"bar";
434 static_assert(wide[0] == L'b', "");
436 constexpr const char32_t *u32 = U"abc";
437 static_assert(u32[1] == U'b', "");
439 constexpr char32_t c = U'\U0001F60E';
440 static_assert(c == 0x0001F60EL, "");
442 constexpr char k = -1;
443 static_assert(k == -1, "");
445 static_assert('\N{LATIN CAPITAL LETTER E}' == 'E', "");
446 static_assert('\t' == 9, "");
448 #pragma clang diagnostic push
449 #pragma clang diagnostic ignored "-Wmultichar"
450 constexpr int mc = 'abc';
451 static_assert(mc == 'abc', "");
452 __WCHAR_TYPE__ wm = L'abc'; // ref-error{{wide character literals may not contain multiple characters}} \
453 // expected-error{{wide character literals may not contain multiple characters}}
454 __WCHAR_TYPE__ wu = u'abc'; // ref-error{{Unicode character literals may not contain multiple characters}} \
455 // expected-error{{Unicode character literals may not contain multiple characters}}
456 __WCHAR_TYPE__ wU = U'abc'; // ref-error{{Unicode character literals may not contain multiple characters}} \
457 // expected-error{{Unicode character literals may not contain multiple characters}}
458 #if __cplusplus > 201103L
459 __WCHAR_TYPE__ wu8 = u8'abc'; // ref-error{{Unicode character literals may not contain multiple characters}} \
460 // expected-error{{Unicode character literals may not contain multiple characters}}
461 #endif
463 #pragma clang diagnostic pop
465 constexpr char foo[12] = "abc";
466 static_assert(foo[0] == 'a', "");
467 static_assert(foo[1] == 'b', "");
468 static_assert(foo[2] == 'c', "");
469 static_assert(foo[3] == 0, "");
470 static_assert(foo[11] == 0, "");
472 constexpr char foo2[] = "abc\0def";
473 static_assert(foo2[0] == 'a', "");
474 static_assert(foo2[3] == '\0', "");
475 static_assert(foo2[6] == 'f', "");
476 static_assert(foo2[7] == '\0', "");
477 static_assert(foo2[8] == '\0', ""); // expected-error {{not an integral constant expression}} \
478 // expected-note {{read of dereferenced one-past-the-end pointer}} \
479 // ref-error {{not an integral constant expression}} \
480 // ref-note {{read of dereferenced one-past-the-end pointer}}
482 constexpr char foo3[4] = "abc";
483 static_assert(foo3[3] == '\0', "");
484 static_assert(foo3[4] == '\0', ""); // expected-error {{not an integral constant expression}} \
485 // expected-note {{read of dereferenced one-past-the-end pointer}} \
486 // ref-error {{not an integral constant expression}} \
487 // ref-note {{read of dereferenced one-past-the-end pointer}}
489 constexpr char foo4[2] = "abcd"; // expected-error {{initializer-string for char array is too long}} \
490 // ref-error {{initializer-string for char array is too long}}
491 static_assert(foo4[0] == 'a', "");
492 static_assert(foo4[1] == 'b', "");
493 static_assert(foo4[2] == '\0', ""); // expected-error {{not an integral constant expression}} \
494 // expected-note {{read of dereferenced one-past-the-end pointer}} \
495 // ref-error {{not an integral constant expression}} \
496 // ref-note {{read of dereferenced one-past-the-end pointer}}
498 constexpr char foo5[12] = "abc\xff";
499 #if defined(__CHAR_UNSIGNED__) || __CHAR_BIT__ > 8
500 static_assert(foo5[3] == 255, "");
501 #else
502 static_assert(foo5[3] == -1, "");
503 #endif
506 #if __cplusplus > 201402L
507 namespace IncDec {
508 constexpr int zero() {
509 int a = 0;
510 a++;
511 ++a;
512 a--;
513 --a;
514 return a;
516 static_assert(zero() == 0, "");
518 constexpr int preInc() {
519 int a = 0;
520 return ++a;
522 static_assert(preInc() == 1, "");
524 constexpr int postInc() {
525 int a = 0;
526 return a++;
528 static_assert(postInc() == 0, "");
530 constexpr int preDec() {
531 int a = 0;
532 return --a;
534 static_assert(preDec() == -1, "");
536 constexpr int postDec() {
537 int a = 0;
538 return a--;
540 static_assert(postDec() == 0, "");
542 constexpr int three() {
543 int a = 0;
544 return ++a + ++a; // expected-warning {{multiple unsequenced modifications to 'a'}} \
545 // ref-warning {{multiple unsequenced modifications to 'a'}} \
548 static_assert(three() == 3, "");
550 constexpr bool incBool() {
551 bool b = false;
552 return ++b; // expected-error {{ISO C++17 does not allow incrementing expression of type bool}} \
553 // ref-error {{ISO C++17 does not allow incrementing expression of type bool}}
555 static_assert(incBool(), "");
557 /// FIXME: The diagnostics for pre-inc/dec of pointers doesn't match the
558 /// current interpreter. But they are stil OK.
559 template<typename T, bool Inc, bool Pre>
560 constexpr int uninit() {
561 T a;
562 if constexpr (Inc) {
563 if (Pre)
564 ++a; // ref-note 3{{increment of uninitialized}} \
565 // expected-note 2{{increment of uninitialized}} \
566 // expected-note {{read of uninitialized}}
567 else
568 a++; // ref-note 2{{increment of uninitialized}} \
569 // expected-note 2{{increment of uninitialized}}
570 } else {
571 if (Pre)
572 --a; // ref-note 3{{decrement of uninitialized}} \
573 // expected-note 2{{decrement of uninitialized}} \
574 // expected-note {{read of uninitialized}}
575 else
576 a--; // ref-note 2{{decrement of uninitialized}} \
577 // expected-note 2{{decrement of uninitialized}}
579 return 1;
581 static_assert(uninit<int, true, true>(), ""); // ref-error {{not an integral constant expression}} \
582 // ref-note {{in call to 'uninit<int, true, true>()'}} \
583 // expected-error {{not an integral constant expression}} \
584 // expected-note {{in call to 'uninit()'}}
585 static_assert(uninit<int, false, true>(), ""); // ref-error {{not an integral constant expression}} \
586 // ref-note {{in call to 'uninit<int, false, true>()'}} \
587 // expected-error {{not an integral constant expression}} \
588 // expected-note {{in call to 'uninit()'}}
590 static_assert(uninit<float, true, true>(), ""); // ref-error {{not an integral constant expression}} \
591 // ref-note {{in call to 'uninit<float, true, true>()'}} \
592 // expected-error {{not an integral constant expression}} \
593 // expected-note {{in call to 'uninit()'}}
594 static_assert(uninit<float, false, true>(), ""); // ref-error {{not an integral constant expression}} \
595 // ref-note {{in call to 'uninit<float, false, true>()'}} \
596 // expected-error {{not an integral constant expression}} \
597 // expected-note {{in call to 'uninit()'}}
598 static_assert(uninit<float, true, false>(), ""); // ref-error {{not an integral constant expression}} \
599 // ref-note {{in call to 'uninit<float, true, false>()'}} \
600 // expected-error {{not an integral constant expression}} \
601 // expected-note {{in call to 'uninit()'}}
602 static_assert(uninit<float, false, false>(), ""); // ref-error {{not an integral constant expression}} \
603 // ref-note {{in call to 'uninit<float, false, false>()'}} \
604 // expected-error {{not an integral constant expression}} \
605 // expected-note {{in call to 'uninit()'}}
607 static_assert(uninit<int*, true, true>(), ""); // ref-error {{not an integral constant expression}} \
608 // ref-note {{in call to 'uninit<int *, true, true>()'}} \
609 // expected-error {{not an integral constant expression}} \
610 // expected-note {{in call to 'uninit()'}}
611 static_assert(uninit<int*, false, true>(), ""); // ref-error {{not an integral constant expression}} \
612 // ref-note {{in call to 'uninit<int *, false, true>()'}} \
613 // expected-error {{not an integral constant expression}} \
614 // expected-note {{in call to 'uninit()'}}
615 static_assert(uninit<int*, true, false>(), ""); // ref-error {{not an integral constant expression}} \
616 // ref-note {{in call to 'uninit<int *, true, false>()'}} \
617 // expected-error {{not an integral constant expression}} \
618 // expected-note {{in call to 'uninit()'}}
619 static_assert(uninit<int*, false, false>(), ""); // ref-error {{not an integral constant expression}} \
620 // ref-note {{in call to 'uninit<int *, false, false>()'}} \
621 // expected-error {{not an integral constant expression}} \
622 // expected-note {{in call to 'uninit()'}}
624 constexpr int OverFlow() { // ref-error {{never produces a constant expression}} \
625 // expected-error {{never produces a constant expression}}
626 int a = INT_MAX;
627 ++a; // ref-note 2{{is outside the range}} \
628 // expected-note 2{{is outside the range}}
629 return -1;
631 static_assert(OverFlow() == -1, ""); // expected-error {{not an integral constant expression}} \
632 // expected-note {{in call to 'OverFlow()'}} \
633 // ref-error {{not an integral constant expression}} \
634 // ref-note {{in call to 'OverFlow()'}}
637 constexpr int UnderFlow() { // ref-error {{never produces a constant expression}} \
638 // expected-error {{never produces a constant expression}}
639 int a = INT_MIN;
640 --a; // ref-note 2{{is outside the range}} \
641 // expected-note 2{{is outside the range}}
642 return -1;
644 static_assert(UnderFlow() == -1, ""); // expected-error {{not an integral constant expression}} \
645 // expected-note {{in call to 'UnderFlow()'}} \
646 // ref-error {{not an integral constant expression}} \
647 // ref-note {{in call to 'UnderFlow()'}}
649 constexpr int getTwo() {
650 int i = 1;
651 return (i += 1);
653 static_assert(getTwo() == 2, "");
655 constexpr int sub(int a) {
656 return (a -= 2);
658 static_assert(sub(7) == 5, "");
660 constexpr int add(int a, int b) {
661 a += b; // expected-note {{is outside the range of representable values}} \
662 // ref-note {{is outside the range of representable values}}
663 return a;
665 static_assert(add(1, 2) == 3, "");
666 static_assert(add(INT_MAX, 1) == 0, ""); // expected-error {{not an integral constant expression}} \
667 // expected-note {{in call to 'add}} \
668 // ref-error {{not an integral constant expression}} \
669 // ref-note {{in call to 'add}}
671 constexpr int sub(int a, int b) {
672 a -= b; // expected-note {{is outside the range of representable values}} \
673 // ref-note {{is outside the range of representable values}}
674 return a;
676 static_assert(sub(10, 20) == -10, "");
677 static_assert(sub(INT_MIN, 1) == 0, ""); // expected-error {{not an integral constant expression}} \
678 // expected-note {{in call to 'sub}} \
679 // ref-error {{not an integral constant expression}} \
680 // ref-note {{in call to 'sub}}
682 constexpr int subAll(int a) {
683 return (a -= a);
685 static_assert(subAll(213) == 0, "");
687 constexpr bool BoolOr(bool b1, bool b2) {
688 bool a;
689 a = b1;
690 a |= b2;
691 return a;
693 static_assert(BoolOr(true, true), "");
694 static_assert(BoolOr(true, false), "");
695 static_assert(BoolOr(false, true), "");
696 static_assert(!BoolOr(false, false), "");
698 constexpr int IntOr(unsigned a, unsigned b) {
699 unsigned r;
700 r = a;
701 r |= b;
702 return r;
704 static_assert(IntOr(10, 1) == 11, "");
705 static_assert(IntOr(1337, -1) == -1, "");
706 static_assert(IntOr(0, 12) == 12, "");
708 constexpr bool BoolAnd(bool b1, bool b2) {
709 bool a;
710 a = b1;
711 a &= b2;
712 return a;
714 static_assert(BoolAnd(true, true), "");
715 static_assert(!BoolAnd(true, false), "");
716 static_assert(!BoolAnd(false, true), "");
717 static_assert(!BoolAnd(false, false), "");
719 constexpr int IntAnd(unsigned a, unsigned b) {
720 unsigned r;
721 r = a;
722 r &= b;
723 return r;
725 static_assert(IntAnd(10, 1) == 0, "");
726 static_assert(IntAnd(1337, -1) == 1337, "");
727 static_assert(IntAnd(0, 12) == 0, "");
729 constexpr bool BoolXor(bool b1, bool b2) {
730 bool a;
731 a = b1;
732 a ^= b2;
733 return a;
735 static_assert(!BoolXor(true, true), "");
736 static_assert(BoolXor(true, false), "");
737 static_assert(BoolXor(false, true), "");
738 static_assert(!BoolXor(false, false), "");
740 constexpr int IntXor(unsigned a, unsigned b) {
741 unsigned r;
742 r = a;
743 r ^= b;
744 return r;
746 static_assert(IntXor(10, 1) == 11, "");
747 static_assert(IntXor(10, 10) == 0, "");
748 static_assert(IntXor(12, true) == 13, "");
750 constexpr bool BoolRem(bool b1, bool b2) {
751 bool a;
752 a = b1;
753 a %= b2;
754 return a;
756 static_assert(!BoolRem(true, true), "");
757 static_assert(!BoolRem(false, true), "");
759 constexpr int IntRem(int a, int b) {
760 int r;
761 r = a;
762 r %= b; // expected-note {{division by zero}} \
763 // ref-note {{division by zero}} \
764 // expected-note {{outside the range of representable values}} \
765 // ref-note {{outside the range of representable values}}
766 return r;
768 static_assert(IntRem(2, 2) == 0, "");
769 static_assert(IntRem(2, 1) == 0, "");
770 static_assert(IntRem(9, 7) == 2, "");
771 static_assert(IntRem(5, 0) == 0, ""); // expected-error {{not an integral constant expression}} \
772 // expected-note {{in call to 'IntRem(5, 0)'}} \
773 // ref-error {{not an integral constant expression}} \
774 // ref-note {{in call to 'IntRem(5, 0)'}}
776 static_assert(IntRem(INT_MIN, -1) == 0, ""); // expected-error {{not an integral constant expression}} \
777 // expected-note {{in call to 'IntRem}} \
778 // ref-error {{not an integral constant expression}} \
779 // ref-note {{in call to 'IntRem}}
783 constexpr bool BoolDiv(bool b1, bool b2) {
784 bool a;
785 a = b1;
786 a /= b2;
787 return a;
789 static_assert(BoolDiv(true, true), "");
790 static_assert(!BoolDiv(false, true), "");
792 constexpr int IntDiv(int a, int b) {
793 int r;
794 r = a;
795 r /= b; // expected-note {{division by zero}} \
796 // ref-note {{division by zero}} \
797 // expected-note {{outside the range of representable values}} \
798 // ref-note {{outside the range of representable values}}
799 return r;
801 static_assert(IntDiv(2, 2) == 1, "");
802 static_assert(IntDiv(12, 20) == 0, "");
803 static_assert(IntDiv(2, 1) == 2, "");
804 static_assert(IntDiv(9, 7) == 1, "");
805 static_assert(IntDiv(5, 0) == 0, ""); // expected-error {{not an integral constant expression}} \
806 // expected-note {{in call to 'IntDiv(5, 0)'}} \
807 // ref-error {{not an integral constant expression}} \
808 // ref-note {{in call to 'IntDiv(5, 0)'}}
810 static_assert(IntDiv(INT_MIN, -1) == 0, ""); // expected-error {{not an integral constant expression}} \
811 // expected-note {{in call to 'IntDiv}} \
812 // ref-error {{not an integral constant expression}} \
813 // ref-note {{in call to 'IntDiv}}
815 constexpr bool BoolMul(bool b1, bool b2) {
816 bool a;
817 a = b1;
818 a *= b2;
819 return a;
821 static_assert(BoolMul(true, true), "");
822 static_assert(!BoolMul(true, false), "");
823 static_assert(!BoolMul(false, true), "");
824 static_assert(!BoolMul(false, false), "");
826 constexpr int IntMul(int a, int b) {
827 int r;
828 r = a;
829 r *= b; // expected-note {{is outside the range of representable values of type 'int'}} \
830 // ref-note {{is outside the range of representable values of type 'int'}}
831 return r;
833 static_assert(IntMul(2, 2) == 4, "");
834 static_assert(IntMul(12, 20) == 240, "");
835 static_assert(IntMul(2, 1) == 2, "");
836 static_assert(IntMul(9, 7) == 63, "");
837 static_assert(IntMul(INT_MAX, 2) == 0, ""); // expected-error {{not an integral constant expression}} \
838 // expected-note {{in call to 'IntMul}} \
839 // ref-error {{not an integral constant expression}} \
840 // ref-note {{in call to 'IntMul}}
841 constexpr int arr[] = {1,2,3};
842 constexpr int ptrInc1() {
843 const int *p = arr;
844 p += 2;
845 return *p;
847 static_assert(ptrInc1() == 3, "");
849 constexpr int ptrInc2() {
850 const int *p = arr;
851 return *(p += 1);
853 static_assert(ptrInc2() == 2, "");
855 constexpr int ptrInc3() { // expected-error {{never produces a constant expression}} \
856 // ref-error {{never produces a constant expression}}
857 const int *p = arr;
858 p += 12; // expected-note {{cannot refer to element 12 of array of 3 elements}} \
859 // ref-note {{cannot refer to element 12 of array of 3 elements}}
860 return *p;
863 constexpr int ptrIncDec1() {
864 const int *p = arr;
865 p += 2;
866 p -= 1;
867 return *p;
869 static_assert(ptrIncDec1() == 2, "");
871 constexpr int ptrDec1() { // expected-error {{never produces a constant expression}} \
872 // ref-error {{never produces a constant expression}}
873 const int *p = arr;
874 p -= 1; // expected-note {{cannot refer to element -1 of array of 3 elements}} \
875 // ref-note {{cannot refer to element -1 of array of 3 elements}}
876 return *p;
879 /// This used to leave a 0 on the stack instead of the previous
880 /// value of a.
881 constexpr int bug1Inc() {
882 int a = 3;
883 int b = a++;
884 return b;
886 static_assert(bug1Inc() == 3);
888 constexpr int bug1Dec() {
889 int a = 3;
890 int b = a--;
891 return b;
893 static_assert(bug1Dec() == 3);
895 constexpr int f() {
896 int a[] = {1,2};
897 int i = 0;
899 // RHS should be evaluated before LHS, so this should
900 // write to a[1];
901 a[i++] += ++i;
903 return a[1];
905 static_assert(f() == 3, "");
907 #endif
909 namespace CompoundLiterals {
910 constexpr int get5() {
911 return (int[]){1,2,3,4,5}[4];
913 static_assert(get5() == 5, "");
915 constexpr int get6(int f = (int[]){1,2,6}[2]) { // ref-note {{subexpression not valid in a constant expression}} \
916 // ref-note {{declared here}}
917 return f;
919 static_assert(get6(6) == 6, "");
920 // FIXME: Who's right here?
921 static_assert(get6() == 6, ""); // ref-error {{not an integral constant expression}}
923 constexpr int x = (int){3};
924 static_assert(x == 3, "");
925 #if __cplusplus >= 201402L
926 constexpr int getX() {
927 int x = (int){3};
928 x = (int){5};
929 return x;
931 static_assert(getX() == 5, "");
932 #endif
934 #if __cplusplus >= 202002L
935 constexpr int get3() {
936 int m;
937 m = (int){3};
938 return m;
940 static_assert(get3() == 3, "");
941 #endif
944 namespace TypeTraits {
945 static_assert(__is_trivial(int), "");
946 static_assert(__is_trivial(float), "");
947 static_assert(__is_trivial(E), "");
948 struct S{};
949 static_assert(__is_trivial(S), "");
950 struct S2 {
951 S2() {}
953 static_assert(!__is_trivial(S2), "");
955 template <typename T>
956 struct S3 {
957 constexpr bool foo() const { return __is_trivial(T); }
959 struct T {
960 ~T() {}
962 struct U {};
963 static_assert(S3<U>{}.foo(), "");
964 static_assert(!S3<T>{}.foo(), "");
967 #if __cplusplus >= 201402L
968 constexpr int ignoredDecls() {
969 static_assert(true, "");
970 struct F { int a; };
971 enum E { b };
972 using A = int;
973 typedef int Z;
975 return F{12}.a;
977 static_assert(ignoredDecls() == 12, "");
979 namespace DiscardExprs {
980 #pragma clang diagnostic push
981 #pragma clang diagnostic ignored "-Wunused-value"
983 struct A{ int a; };
984 constexpr int ignoredExprs() {
985 (void)(1 / 2);
986 A a{12};
988 (void)a;
989 (a);
991 /// Ignored MaterializeTemporaryExpr.
992 struct B{ const int &a; };
993 (void)B{12};
995 (void)5, (void)6;
997 1 ? 0 : 1;
998 __is_trivial(int);
1000 (int){1};
1001 (int[]){1,2,3};
1002 int arr[] = {1,2,3};
1003 arr[0];
1004 "a";
1005 'b';
1006 sizeof(int);
1007 alignof(int);
1009 (short)5;
1010 (bool)1;
1011 __null;
1012 __builtin_offsetof(A, a);
1013 1,2;
1015 return 0;
1017 static_assert(ignoredExprs() == 0, "");
1019 constexpr int oh_my(int x) {
1020 (int){ x++ };
1021 return x;
1023 static_assert(oh_my(0) == 1, "");
1025 constexpr int oh_my2(int x) {
1026 int y{x++};
1027 return x;
1030 static_assert(oh_my2(0) == 1, "");
1033 /// Ignored comma expressions still have their
1034 /// expressions evaluated.
1035 constexpr int Comma(int start) {
1036 int i = start;
1038 (void)i++;
1039 (void)i++,(void)i++;
1040 return i;
1042 constexpr int Value = Comma(5);
1043 static_assert(Value == 8, "");
1045 /// Ignored MemberExprs need to still evaluate the Base
1046 /// expr.
1047 constexpr A callme(int &i) {
1048 ++i;
1049 return A{};
1051 constexpr int ignoredMemberExpr() {
1052 int i = 0;
1053 callme(i).a;
1054 return i;
1056 static_assert(ignoredMemberExpr() == 1, "");
1058 template <int I>
1059 constexpr int foo() {
1061 return I;
1063 static_assert(foo<3>() == 3, "");
1065 #pragma clang diagnostic pop
1067 #endif
1069 namespace PredefinedExprs {
1070 #if __cplusplus >= 201402L
1071 template<typename CharT>
1072 constexpr bool strings_match(const CharT *str1, const CharT *str2) {
1073 while (*str1 && *str2) {
1074 if (*str1++ != *str2++)
1075 return false;
1078 return *str1 == *str2;
1081 void foo() {
1082 static_assert(strings_match(__FUNCSIG__, "void __cdecl PredefinedExprs::foo(void)"), "");
1083 static_assert(strings_match(L__FUNCSIG__, L"void __cdecl PredefinedExprs::foo(void)"), "");
1084 static_assert(strings_match(L__FUNCTION__, L"foo"), "");
1085 static_assert(strings_match(__FUNCTION__, "foo"), "");
1086 static_assert(strings_match(__func__, "foo"), "");
1087 static_assert(strings_match(__PRETTY_FUNCTION__, "void PredefinedExprs::foo()"), "");
1090 constexpr char heh(unsigned index) {
1091 __FUNCTION__; // ref-warning {{result unused}} \
1092 // expected-warning {{result unused}}
1093 __extension__ __FUNCTION__; // ref-warning {{result unused}} \
1094 // expected-warning {{result unused}}
1095 return __FUNCTION__[index];
1097 static_assert(heh(0) == 'h', "");
1098 static_assert(heh(1) == 'e', "");
1099 static_assert(heh(2) == 'h', "");
1100 #endif
1103 namespace NE {
1104 constexpr int foo() noexcept {
1105 return 1;
1107 static_assert(noexcept(foo()), "");
1108 constexpr int foo2() {
1109 return 1;
1111 static_assert(!noexcept(foo2()), "");
1113 #if __cplusplus > 201402L
1114 constexpr int a() {
1115 int b = 0;
1116 (void)noexcept(++b); // expected-warning {{expression with side effects has no effect in an unevaluated context}} \
1117 // ref-warning {{expression with side effects has no effect in an unevaluated context}}
1119 return b;
1121 static_assert(a() == 0, "");
1122 #endif
1125 namespace PointerCasts {
1126 constexpr int M = 10;
1127 constexpr const int *P = &M;
1128 constexpr intptr_t A = (intptr_t)P; // ref-error {{must be initialized by a constant expression}} \
1129 // ref-note {{cast that performs the conversions of a reinterpret_cast}} \
1130 // expected-error {{must be initialized by a constant expression}} \
1131 // expected-note {{cast that performs the conversions of a reinterpret_cast}}
1133 int array[(intptr_t)(char*)0]; // ref-warning {{variable length array folded to constant array}} \
1134 // expected-warning {{variable length array folded to constant array}}
1137 namespace InvalidDeclRefs {
1138 bool b00; // ref-note {{declared here}} \
1139 // expected-note {{declared here}}
1140 static_assert(b00, ""); // ref-error {{not an integral constant expression}} \
1141 // ref-note {{read of non-const variable}} \
1142 // expected-error {{not an integral constant expression}} \
1143 // expected-note {{read of non-const variable}}
1145 float b01; // ref-note {{declared here}} \
1146 // expected-note {{declared here}}
1147 static_assert(b01, ""); // ref-error {{not an integral constant expression}} \
1148 // ref-note {{read of non-constexpr variable}} \
1149 // expected-error {{not an integral constant expression}} \
1150 // expected-note {{read of non-constexpr variable}}
1152 extern const int b02; // ref-note {{declared here}} \
1153 // expected-note {{declared here}}
1154 static_assert(b02, ""); // ref-error {{not an integral constant expression}} \
1155 // ref-note {{initializer of 'b02' is unknown}} \
1156 // expected-error {{not an integral constant expression}} \
1157 // expected-note {{initializer of 'b02' is unknown}}
1159 /// FIXME: This should also be diagnosed in the new interpreter.
1160 int b03 = 3; // ref-note {{declared here}}
1161 static_assert(b03, ""); // ref-error {{not an integral constant expression}} \
1162 // ref-note {{read of non-const variable}}