1451 lines · cpp
1// RUN: %clang_cc1 -Wno-vla -fms-extensions -std=c++11 -fexperimental-new-constant-interpreter -verify=expected,both %s2// RUN: %clang_cc1 -Wno-vla -fms-extensions -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s3// RUN: %clang_cc1 -Wno-vla -fms-extensions -std=c++11 -verify=ref,both %s4// RUN: %clang_cc1 -Wno-vla -fms-extensions -std=c++20 -verify=ref,both %s5 6#define INT_MIN (~__INT_MAX__)7#define INT_MAX __INT_MAX__8 9typedef __INTPTR_TYPE__ intptr_t;10typedef __PTRDIFF_TYPE__ ptrdiff_t;11 12 13static_assert(true, "");14static_assert(false, ""); // both-error{{failed}}15static_assert(nullptr == nullptr, "");16static_assert(__null == __null, "");17static_assert(1 == 1, "");18static_assert(1 == 3, ""); // both-error{{failed}}19 20constexpr void* v = nullptr;21static_assert(__null == v, "");22 23constexpr int number = 10;24static_assert(number == 10, "");25static_assert(number != 10, ""); // both-error{{failed}} \26 // both-note{{evaluates to}}27 28static_assert(__objc_yes, "");29static_assert(!__objc_no, "");30 31static_assert((long long)0x00000000FFFF0000 == 4294901760, "");32 33constexpr bool b = number;34static_assert(b, "");35constexpr int one = true;36static_assert(one == 1, "");37 38constexpr bool b2 = bool();39static_assert(!b2, "");40 41constexpr int Failed1 = 1 / 0; // both-error {{must be initialized by a constant expression}} \42 // both-note {{division by zero}} \43 // both-note {{declared here}}44constexpr int Failed2 = Failed1 + 1; // both-error {{must be initialized by a constant expression}} \45 // both-note {{declared here}} \46 // both-note {{initializer of 'Failed1' is not a constant expression}}47static_assert(Failed2 == 0, ""); // both-error {{not an integral constant expression}} \48 // both-note {{initializer of 'Failed2' is not a constant expression}}49 50const int x = *(volatile int*)0x1234;51static_assert((void{}, true), "");52 53namespace ScalarTypes {54 constexpr int ScalarInitInt = int();55 static_assert(ScalarInitInt == 0, "");56 constexpr float ScalarInitFloat = float();57 static_assert(ScalarInitFloat == 0.0f, "");58 59 static_assert(decltype(nullptr)() == nullptr, "");60 61 template<typename T>62 constexpr T getScalar() { return T(); }63 64 static_assert(getScalar<const int>() == 0, "");65 static_assert(getScalar<const double>() == 0.0, "");66 67 static_assert(getScalar<void*>() == nullptr, "");68 static_assert(getScalar<void(*)(void)>() == nullptr, "");69 70 enum E {71 First = 0,72 };73 static_assert(getScalar<E>() == First, "");74 75 struct S {76 int v;77 };78 constexpr int S::* MemberPtr = &S::v;79 static_assert(getScalar<decltype(MemberPtr)>() == nullptr, "");80 81#if __cplusplus >= 201402L82 constexpr void Void(int n) {83 void(n + 1);84 void();85 }86 constexpr int void_test = (Void(0), 1);87 static_assert(void_test == 1, "");88#endif89}90 91namespace IntegralCasts {92 constexpr int i = 12;93 constexpr unsigned int ui = i;94 static_assert(ui == 12, "");95 constexpr unsigned int ub = !false;96 static_assert(ub == 1, "");97 98 constexpr int si = ui;99 static_assert(si == 12, "");100 constexpr int sb = true;101 static_assert(sb == 1, "");102 103 constexpr int zero = 0;104 constexpr unsigned int uzero = 0;105 constexpr bool bs = i;106 static_assert(bs, "");107 constexpr bool bu = ui;108 static_assert(bu, "");109 constexpr bool ns = zero;110 static_assert(!ns, "");111 constexpr bool nu = uzero;112 static_assert(!nu, "");113};114 115constexpr int UninitI; // both-error {{must be initialized by a constant expression}}116constexpr int *UninitPtr; // both-error {{must be initialized by a constant expression}}117 118constexpr bool getTrue() { return true; }119constexpr bool getFalse() { return false; }120constexpr void* getNull() { return nullptr; }121 122constexpr int neg(int m) { return -m; }123constexpr bool inv(bool b) { return !b; }124 125static_assert(12, "");126static_assert(12 == -(-(12)), "");127static_assert(!false, "");128static_assert(!!true, "");129static_assert(!!true == !false, "");130static_assert(true == 1, "");131static_assert(false == 0, "");132static_assert(!5 == false, "");133static_assert(!0, "");134static_assert(-true, "");135static_assert(-false, ""); //both-error{{failed}}136 137static_assert(~0 == -1, "");138static_assert(~1 == -2, "");139static_assert(~-1 == 0, "");140static_assert(~255 == -256, "");141static_assert(~INT_MIN == INT_MAX, "");142static_assert(~INT_MAX == INT_MIN, "");143 144static_assert(-(1 << 31), ""); // both-error {{not an integral constant expression}} \145 // both-note {{outside the range of representable values}}146 147namespace PrimitiveEmptyInitList {148 constexpr int a = {};149 static_assert(a == 0, "");150 constexpr bool b = {};151 static_assert(!b, "");152 constexpr double d = {};153 static_assert(d == 0.0, "");154}155 156 157enum E {};158constexpr E e = static_cast<E>(0);159static_assert(~e == -1, "");160 161 162constexpr int m = 10;163constexpr const int *p = &m;164static_assert(p != nullptr, "");165static_assert(*p == 10, "");166 167constexpr const int* getIntPointer() {168 return &m;169}170static_assert(getIntPointer() == &m, "");171static_assert(*getIntPointer() == 10, "");172 173constexpr int gimme(int k) {174 return k;175}176static_assert(gimme(5) == 5, "");177 178namespace PointerToBool {179 180 constexpr void *N = nullptr;181 constexpr bool B = N;182 static_assert(!B, "");183 static_assert(!N, "");184 185 constexpr float F = 1.0;186 constexpr const float *FP = &F;187 static_assert(FP, "");188 static_assert(!!FP, "");189}190 191namespace PointerComparison {192 193 struct S { int a, b; } s;194 constexpr void *null = 0;195 constexpr void *pv = (void*)&s.a;196 constexpr void *qv = (void*)&s.b;197 constexpr bool v1 = null < (int*)0;198 constexpr bool v2 = null < pv; // both-error {{must be initialized by a constant expression}} \199 // both-note {{comparison between pointers to unrelated objects 'nullptr' and '&s.a' has unspecified value}}200 201 constexpr bool v3 = null == pv; // ok202 constexpr bool v4 = qv == pv; // ok203 204 constexpr bool v5 = qv >= pv;205 constexpr bool v8 = qv > (void*)&s.a;206 constexpr bool v6 = qv > null; // both-error {{must be initialized by a constant expression}} \207 // both-note {{comparison between pointers to unrelated objects '&s.b' and 'nullptr' has unspecified value}}208 209 constexpr bool v7 = qv <= (void*)&s.b; // ok210 211 constexpr ptrdiff_t m = &m - &m;212 static_assert(m == 0, "");213 214 constexpr ptrdiff_t m2 = (&m2 + 1) - (&m2 + 1);215 static_assert(m2 == 0, "");216 217 constexpr long m3 = (&m3 + 1) - (&m3);218 static_assert(m3 == 1, "");219 220 constexpr long m4 = &m4 + 2 - &m4; // both-error {{must be initialized by a constant expression}} \221 // both-note {{cannot refer to element 2 of non-array object}}222}223 224namespace SizeOf {225 static_assert(alignof(char&) == 1, "");226 227 constexpr int soint = sizeof(int);228 constexpr int souint = sizeof(unsigned int);229 static_assert(soint == souint, "");230 231 static_assert(sizeof(&soint) == sizeof(void*), "");232 static_assert(sizeof(&soint) == sizeof(nullptr), "");233 234 static_assert(sizeof(long) == sizeof(unsigned long), "");235 static_assert(sizeof(char) == sizeof(unsigned char), "");236 237 constexpr int N = 4;238 constexpr int arr[N] = {1,2,3,4};239 static_assert(sizeof(arr) == N * sizeof(int), "");240 static_assert(sizeof(arr) == N * sizeof(arr[0]), "");241 242 constexpr bool arrB[N] = {true, true, true, true};243 static_assert(sizeof(arrB) == N * sizeof(bool), "");244 245 static_assert(sizeof(bool) == 1, "");246 static_assert(sizeof(char) == 1, "");247 248 constexpr int F = sizeof(void); // both-error{{incomplete type 'void'}}249 250 constexpr int F2 = sizeof(gimme); // both-error{{to a function type}}251 252 253 struct S {254 void func();255 };256 constexpr void (S::*Func)() = &S::func;257 static_assert(sizeof(Func) == sizeof(&S::func), "");258 259 260 void func() {261 int n = 12;262 constexpr int oofda = sizeof(int[n++]); // both-error {{must be initialized by a constant expression}}263 }264 265#if __cplusplus >= 201402L266 constexpr int IgnoredRejected() { // both-error {{never produces a constant expression}}267 int n = 0;268 sizeof(int[n++]); // both-warning {{expression result unused}} \269 // both-note 2{{subexpression not valid in a constant expression}}270 return n;271 }272 static_assert(IgnoredRejected() == 0, ""); // both-error {{not an integral constant expression}} \273 // both-note {{in call to 'IgnoredRejected()'}}274#endif275 276 277#if __cplusplus >= 202002L278 /// FIXME: The following code should be accepted.279 consteval int foo(int n) { // both-error {{consteval function never produces a constant expression}}280 return sizeof(int[n]); // both-note 3{{not valid in a constant expression}}281 }282 constinit int var = foo(5); // both-error {{not a constant expression}} \283 // both-note 2{{in call to}} \284 // both-error {{does not have a constant initializer}} \285 // both-note {{required by 'constinit' specifier}}286 287#endif288};289 290namespace rem {291 static_assert(2 % 2 == 0, "");292 static_assert(2 % 1 == 0, "");293 static_assert(-3 % 4 == -3, "");294 static_assert(4 % -2 == 0, "");295 static_assert(-3 % -4 == -3, "");296 297 constexpr int zero() { return 0; }298 static_assert(10 % zero() == 20, ""); // both-error {{not an integral constant expression}} \299 // both-note {{division by zero}}300 301 static_assert(true % true == 0, "");302 static_assert(false % true == 0, "");303 static_assert(true % false == 10, ""); // both-error {{not an integral constant expression}} \304 // both-note {{division by zero}}305 constexpr int x = INT_MIN % - 1; // both-error {{must be initialized by a constant expression}} \306 // both-note {{value 2147483648 is outside the range}}307};308 309namespace div {310 constexpr int zero() { return 0; }311 static_assert(12 / 3 == 4, "");312 static_assert(12 / zero() == 12, ""); // both-error {{not an integral constant expression}} \313 // both-note {{division by zero}}314 static_assert(12 / -3 == -4, "");315 static_assert(-12 / 3 == -4, "");316 317 318 constexpr int LHS = 12;319 constexpr long unsigned RHS = 3;320 static_assert(LHS / RHS == 4, "");321 322 constexpr int x = INT_MIN / - 1; // both-error {{must be initialized by a constant expression}} \323 // both-note {{value 2147483648 is outside the range}}324};325 326namespace cond {327 constexpr bool isEven(int n) {328 return n % 2 == 0 ? true : false;329 }330 static_assert(isEven(2), "");331 static_assert(!isEven(3), "");332 static_assert(isEven(100), "");333 334 constexpr int M = 5 ? 10 : 20;335 static_assert(M == 10, "");336 337 static_assert(5 ? 13 : 16 == 13, "");338 static_assert(0 ? 13 : 16 == 16, "");339 340 static_assert(number ?: -15 == number, "");341 static_assert(0 ?: 100 == 100 , "");342 343#if __cplusplus >= 201402L344 constexpr int N = 20;345 constexpr int foo() {346 int m = N > 0 ? 5 : 10;347 348 return m == 5 ? isEven(m) : true;349 }350 static_assert(foo() == false, "");351 352 constexpr int dontCallMe(unsigned m) {353 if (m == 0) return 0;354 return dontCallMe(m - 2);355 }356 357 // Can't call this because it will run into infinite recursion.358 constexpr int assertNotReached() {359 return dontCallMe(3);360 }361 362 constexpr int testCond() {363 return true ? 5 : assertNotReached();364 }365 366 constexpr int testCond2() {367 return false ? assertNotReached() : 10;368 }369 370 static_assert(testCond() == 5, "");371 static_assert(testCond2() == 10, "");372 373#endif374 375};376 377namespace band {378 static_assert((10 & 1) == 0, "");379 static_assert((10 & 10) == 10, "");380 381 static_assert((1337 & -1) == 1337, "");382 static_assert((0 & gimme(12)) == 0, "");383};384 385namespace bitOr {386 static_assert((10 | 1) == 11, "");387 static_assert((10 | 10) == 10, "");388 389 static_assert((1337 | -1) == -1, "");390 static_assert((0 | gimme(12)) == 12, "");391 static_assert((12 | true) == 13, "");392};393 394namespace bitXor {395#pragma clang diagnostic push396#pragma clang diagnostic ignored "-Wxor-used-as-pow"397 static_assert((10 ^ 1) == 11, "");398 static_assert((10 ^ 10) == 0, "");399 400 enum {401 ONE = 1,402 };403 404 static_assert((1337 ^ -1) == -1338, "");405 static_assert((0 | gimme(12)) == 12, "");406 static_assert((12 ^ true) == 13, "");407 static_assert((12 ^ ONE) == 13, "");408#pragma clang diagnostic pop409};410 411#if __cplusplus >= 201402L412constexpr bool IgnoredUnary() {413 bool bo = true;414 !bo; // both-warning {{expression result unused}}415 return bo;416}417static_assert(IgnoredUnary(), "");418#endif419 420namespace strings {421 constexpr const char *S = "abc";422 static_assert(S[0] == 97, "");423 static_assert(S[1] == 98, "");424 static_assert(S[2] == 99, "");425 static_assert(S[3] == 0, "");426 427 static_assert("foobar"[2] == 'o', "");428 static_assert(2["foobar"] == 'o', "");429 430 constexpr const wchar_t *wide = L"bar";431 static_assert(wide[0] == L'b', "");432 433 constexpr const char32_t *u32 = U"abc";434 static_assert(u32[1] == U'b', "");435 436 constexpr char32_t c = U'\U0001F60E';437 static_assert(c == 0x0001F60EL, "");438 439 constexpr char k = -1;440 static_assert(k == -1, "");441 442 static_assert('\N{LATIN CAPITAL LETTER E}' == 'E', "");443 static_assert('\t' == 9, "");444 445#pragma clang diagnostic push446#pragma clang diagnostic ignored "-Wmultichar"447 constexpr int mc = 'abc';448 static_assert(mc == 'abc', "");449 __WCHAR_TYPE__ wm = L'abc'; // both-error{{wide character literals may not contain multiple characters}}450 __WCHAR_TYPE__ wu = u'abc'; // both-error{{Unicode character literals may not contain multiple characters}}451 __WCHAR_TYPE__ wU = U'abc'; // both-error{{Unicode character literals may not contain multiple characters}}452#if __cplusplus > 201103L453 __WCHAR_TYPE__ wu8 = u8'abc'; // both-error{{Unicode character literals may not contain multiple characters}}454#endif455 456#pragma clang diagnostic pop457 458 constexpr char foo[12] = "abc";459 static_assert(foo[0] == 'a', "");460 static_assert(foo[1] == 'b', "");461 static_assert(foo[2] == 'c', "");462 static_assert(foo[3] == 0, "");463 static_assert(foo[11] == 0, "");464 465 constexpr char foo2[] = "abc\0def";466 static_assert(foo2[0] == 'a', "");467 static_assert(foo2[3] == '\0', "");468 static_assert(foo2[6] == 'f', "");469 static_assert(foo2[7] == '\0', "");470 static_assert(foo2[8] == '\0', ""); // both-error {{not an integral constant expression}} \471 // both-note {{read of dereferenced one-past-the-end pointer}}472 473 constexpr char foo3[4] = "abc";474 static_assert(foo3[3] == '\0', "");475 static_assert(foo3[4] == '\0', ""); // both-error {{not an integral constant expression}} \476 // both-note {{read of dereferenced one-past-the-end pointer}}477 478 constexpr char foo4[2] = "abcd"; // both-error {{initializer-string for char array is too long}}479 static_assert(foo4[0] == 'a', "");480 static_assert(foo4[1] == 'b', "");481 static_assert(foo4[2] == '\0', ""); // both-error {{not an integral constant expression}} \482 // both-note {{read of dereferenced one-past-the-end pointer}}483 484constexpr char foo5[12] = "abc\xff";485#if defined(__CHAR_UNSIGNED__) || __CHAR_BIT__ > 8486static_assert(foo5[3] == 255, "");487#else488static_assert(foo5[3] == -1, "");489#endif490};491 492#if __cplusplus > 201402L493namespace IncDec {494 constexpr int zero() {495 int a = 0;496 a++;497 ++a;498 a--;499 --a;500 return a;501 }502 static_assert(zero() == 0, "");503 504 constexpr int preInc() {505 int a = 0;506 return ++a;507 }508 static_assert(preInc() == 1, "");509 510 constexpr int postInc() {511 int a = 0;512 return a++;513 }514 static_assert(postInc() == 0, "");515 516 constexpr int preDec() {517 int a = 0;518 return --a;519 }520 static_assert(preDec() == -1, "");521 522 constexpr int postDec() {523 int a = 0;524 return a--;525 }526 static_assert(postDec() == 0, "");527 528 constexpr int three() {529 int a = 0;530 return ++a + ++a; // both-warning {{multiple unsequenced modifications to 'a'}}531 }532 static_assert(three() == 3, "");533 534 constexpr bool incBool() {535 bool b = false;536 return ++b; // both-error {{ISO C++17 does not allow incrementing expression of type bool}}537 }538 static_assert(incBool(), "");539 540 /// FIXME: The diagnostics for pre-inc/dec of pointers doesn't match the541 /// current interpreter. But they are stil OK.542 template<typename T, bool Inc, bool Pre>543 constexpr int uninit() {544 T a;545 if constexpr (Inc) {546 if (Pre)547 ++a; // ref-note 3{{increment of uninitialized}} \548 // expected-note 2{{increment of uninitialized}} \549 // expected-note {{read of uninitialized}}550 else551 a++; // both-note 2{{increment of uninitialized}}552 } else {553 if (Pre)554 --a; // ref-note 3{{decrement of uninitialized}} \555 // expected-note 2{{decrement of uninitialized}} \556 // expected-note {{read of uninitialized}}557 else558 a--; // both-note 2{{decrement of uninitialized}}559 }560 return 1;561 }562 static_assert(uninit<int, true, true>(), ""); // both-error {{not an integral constant expression}} \563 // both-note {{in call to 'uninit<int, true, true>()'}}564 static_assert(uninit<int, false, true>(), ""); // both-error {{not an integral constant expression}} \565 // both-note {{in call to 'uninit<int, false, true>()'}}566 567 static_assert(uninit<float, true, true>(), ""); // both-error {{not an integral constant expression}} \568 // both-note {{in call to 'uninit<float, true, true>()'}}569 static_assert(uninit<float, false, true>(), ""); // both-error {{not an integral constant expression}} \570 // both-note {{in call to 'uninit<float, false, true>()'}}571 static_assert(uninit<float, true, false>(), ""); // both-error {{not an integral constant expression}} \572 // both-note {{in call to 'uninit<float, true, false>()'}}573 static_assert(uninit<float, false, false>(), ""); // both-error {{not an integral constant expression}} \574 // both-note {{in call to 'uninit<float, false, false>()'}}575 576 static_assert(uninit<int*, true, true>(), ""); // both-error {{not an integral constant expression}} \577 // both-note {{in call to 'uninit<int *, true, true>()'}}578 static_assert(uninit<int*, false, true>(), ""); // both-error {{not an integral constant expression}} \579 // both-note {{in call to 'uninit<int *, false, true>()'}}580 static_assert(uninit<int*, true, false>(), ""); // both-error {{not an integral constant expression}} \581 // both-note {{in call to 'uninit<int *, true, false>()'}}582 static_assert(uninit<int*, false, false>(), ""); // both-error {{not an integral constant expression}} \583 // both-note {{in call to 'uninit<int *, false, false>()'}}584 585 constexpr int OverFlow() { // both-error {{never produces a constant expression}}586 int a = INT_MAX;587 ++a; // both-note 2{{is outside the range}}588 return -1;589 }590 static_assert(OverFlow() == -1, ""); // both-error {{not an integral constant expression}} \591 // both-note {{in call to 'OverFlow()'}}592 593 constexpr int UnderFlow() { // both-error {{never produces a constant expression}}594 int a = INT_MIN;595 --a; // both-note 2{{is outside the range}}596 return -1;597 }598 static_assert(UnderFlow() == -1, ""); // both-error {{not an integral constant expression}} \599 // both-note {{in call to 'UnderFlow()'}}600 601 /// This UnaryOperator can't overflow, so we shouldn't diagnose any overflow.602 constexpr int CanOverflow() {603 char c = 127;604 char p;605 ++c;606 c++;607 p = ++c;608 p = c++;609 610 c = -128;611 --c;612 c--;613 p = --c;614 p = ++c;615 616 return 0;617 }618 static_assert(CanOverflow() == 0, "");619 620 constexpr char OverflownChar() {621 char c = 127;622 c++;623 return c;624 }625 static_assert(OverflownChar() == -128, "");626 627 constexpr int getTwo() {628 int i = 1;629 return (i += 1);630 }631 static_assert(getTwo() == 2, "");632 633 constexpr int sub(int a) {634 return (a -= 2);635 }636 static_assert(sub(7) == 5, "");637 638 constexpr int add(int a, int b) {639 a += b; // both-note {{is outside the range of representable values}}640 return a;641 }642 static_assert(add(1, 2) == 3, "");643 static_assert(add(INT_MAX, 1) == 0, ""); // both-error {{not an integral constant expression}} \644 // both-note {{in call to 'add}}645 646 constexpr int sub(int a, int b) {647 a -= b; // both-note {{is outside the range of representable values}}648 return a;649 }650 static_assert(sub(10, 20) == -10, "");651 static_assert(sub(INT_MIN, 1) == 0, ""); // both-error {{not an integral constant expression}} \652 // both-note {{in call to 'sub}}653 654 constexpr int subAll(int a) {655 return (a -= a);656 }657 static_assert(subAll(213) == 0, "");658 659 constexpr bool BoolOr(bool b1, bool b2) {660 bool a;661 a = b1;662 a |= b2;663 return a;664 }665 static_assert(BoolOr(true, true), "");666 static_assert(BoolOr(true, false), "");667 static_assert(BoolOr(false, true), "");668 static_assert(!BoolOr(false, false), "");669 670 constexpr int IntOr(unsigned a, unsigned b) {671 unsigned r;672 r = a;673 r |= b;674 return r;675 }676 static_assert(IntOr(10, 1) == 11, "");677 static_assert(IntOr(1337, -1) == -1, "");678 static_assert(IntOr(0, 12) == 12, "");679 680 constexpr bool BoolAnd(bool b1, bool b2) {681 bool a;682 a = b1;683 a &= b2;684 return a;685 }686 static_assert(BoolAnd(true, true), "");687 static_assert(!BoolAnd(true, false), "");688 static_assert(!BoolAnd(false, true), "");689 static_assert(!BoolAnd(false, false), "");690 691 constexpr int IntAnd(unsigned a, unsigned b) {692 unsigned r;693 r = a;694 r &= b;695 return r;696 }697 static_assert(IntAnd(10, 1) == 0, "");698 static_assert(IntAnd(1337, -1) == 1337, "");699 static_assert(IntAnd(0, 12) == 0, "");700 701 constexpr bool BoolXor(bool b1, bool b2) {702 bool a;703 a = b1;704 a ^= b2;705 return a;706 }707 static_assert(!BoolXor(true, true), "");708 static_assert(BoolXor(true, false), "");709 static_assert(BoolXor(false, true), "");710 static_assert(!BoolXor(false, false), "");711 712 constexpr int IntXor(unsigned a, unsigned b) {713 unsigned r;714 r = a;715 r ^= b;716 return r;717 }718 static_assert(IntXor(10, 1) == 11, "");719 static_assert(IntXor(10, 10) == 0, "");720 static_assert(IntXor(12, true) == 13, "");721 722 constexpr bool BoolRem(bool b1, bool b2) {723 bool a;724 a = b1;725 a %= b2;726 return a;727 }728 static_assert(!BoolRem(true, true), "");729 static_assert(!BoolRem(false, true), "");730 731 constexpr int IntRem(int a, int b) {732 int r;733 r = a;734 r %= b; // both-note {{division by zero}} \735 // both-note {{outside the range of representable values}}736 return r;737 }738 static_assert(IntRem(2, 2) == 0, "");739 static_assert(IntRem(2, 1) == 0, "");740 static_assert(IntRem(9, 7) == 2, "");741 static_assert(IntRem(5, 0) == 0, ""); // both-error {{not an integral constant expression}} \742 // both-note {{in call to 'IntRem(5, 0)'}}743 744 static_assert(IntRem(INT_MIN, -1) == 0, ""); // both-error {{not an integral constant expression}} \745 // both-note {{in call to 'IntRem}}746 747 constexpr bool BoolDiv(bool b1, bool b2) {748 bool a;749 a = b1;750 a /= b2;751 return a;752 }753 static_assert(BoolDiv(true, true), "");754 static_assert(!BoolDiv(false, true), "");755 756 constexpr int IntDiv(int a, int b) {757 int r;758 r = a;759 r /= b; // both-note {{division by zero}} \760 // both-note {{outside the range of representable values}}761 return r;762 }763 static_assert(IntDiv(2, 2) == 1, "");764 static_assert(IntDiv(12, 20) == 0, "");765 static_assert(IntDiv(2, 1) == 2, "");766 static_assert(IntDiv(9, 7) == 1, "");767 static_assert(IntDiv(5, 0) == 0, ""); // both-error {{not an integral constant expression}} \768 // both-note {{in call to 'IntDiv(5, 0)'}}769 770 static_assert(IntDiv(INT_MIN, -1) == 0, ""); // both-error {{not an integral constant expression}} \771 // both-note {{in call to 'IntDiv}}772 773 constexpr bool BoolMul(bool b1, bool b2) {774 bool a;775 a = b1;776 a *= b2;777 return a;778 }779 static_assert(BoolMul(true, true), "");780 static_assert(!BoolMul(true, false), "");781 static_assert(!BoolMul(false, true), "");782 static_assert(!BoolMul(false, false), "");783 784 constexpr int IntMul(int a, int b) {785 int r;786 r = a;787 r *= b; // both-note {{is outside the range of representable values of type 'int'}}788 return r;789 }790 static_assert(IntMul(2, 2) == 4, "");791 static_assert(IntMul(12, 20) == 240, "");792 static_assert(IntMul(2, 1) == 2, "");793 static_assert(IntMul(9, 7) == 63, "");794 static_assert(IntMul(INT_MAX, 2) == 0, ""); // both-error {{not an integral constant expression}} \795 // both-note {{in call to 'IntMul}}796 constexpr int arr[] = {1,2,3};797 constexpr int ptrInc1() {798 const int *p = arr;799 p += 2;800 return *p;801 }802 static_assert(ptrInc1() == 3, "");803 804 constexpr int ptrInc2() {805 const int *p = arr;806 return *(p += 1);807 }808 static_assert(ptrInc2() == 2, "");809 810 constexpr int ptrInc3() { // both-error {{never produces a constant expression}}811 const int *p = arr;812 p += 12; // both-note {{cannot refer to element 12 of array of 3 elements}}813 return *p;814 }815 816 constexpr int ptrIncDec1() {817 const int *p = arr;818 p += 2;819 p -= 1;820 return *p;821 }822 static_assert(ptrIncDec1() == 2, "");823 824 constexpr int ptrDec1() { // both-error {{never produces a constant expression}}825 const int *p = arr;826 p -= 1; // both-note {{cannot refer to element -1 of array of 3 elements}}827 return *p;828 }829 830 /// This used to leave a 0 on the stack instead of the previous831 /// value of a.832 constexpr int bug1Inc() {833 int a = 3;834 int b = a++;835 return b;836 }837 static_assert(bug1Inc() == 3);838 839 constexpr int bug1Dec() {840 int a = 3;841 int b = a--;842 return b;843 }844 static_assert(bug1Dec() == 3);845 846 constexpr int f() {847 int a[] = {1,2};848 int i = 0;849 850 // RHS should be evaluated before LHS, so this should851 // write to a[1];852 a[i++] += ++i;853 854 return a[1];855 }856 static_assert(f() == 3, "");857 858 int nonconst(int a) { // both-note 4{{declared here}}859 static_assert(a++, ""); // both-error {{not an integral constant expression}} \860 // both-note {{function parameter 'a' with unknown value cannot be used in a constant expression}}861 static_assert(a--, ""); // both-error {{not an integral constant expression}} \862 // both-note {{function parameter 'a' with unknown value cannot be used in a constant expression}}863 static_assert(++a, ""); // both-error {{not an integral constant expression}} \864 // both-note {{function parameter 'a' with unknown value cannot be used in a constant expression}}865 static_assert(--a, ""); // both-error {{not an integral constant expression}} \866 // both-note {{function parameter 'a' with unknown value cannot be used in a constant expression}}867 }868 869};870#endif871 872namespace CompoundLiterals {873 constexpr int get5() {874 return (int[]){1,2,3,4,5}[4];875 }876 static_assert(get5() == 5, "");877 878 constexpr int get6(int f = (int[]){1,2,6}[2]) {879 return f;880 }881 static_assert(get6(6) == 6, "");882 static_assert(get6() == 6, "");883 884 constexpr int x = (int){3};885 static_assert(x == 3, "");886#if __cplusplus >= 201402L887 constexpr int getX() {888 int x = (int){3};889 x = (int){5};890 return x;891 }892 static_assert(getX() == 5, "");893#endif894 895#if __cplusplus >= 202002L896 constexpr int get3() {897 int m;898 m = (int){3};899 return m;900 }901 static_assert(get3() == 3, "");902 903 constexpr int *f(int *a=(int[]){1,2,3}) { return a; } // both-note {{temporary created here}}904 constinit int *a1 = f(); // both-error {{variable does not have a constant initializer}} \905 both-note {{required by 'constinit' specifier here}} \906 both-note {{pointer to subobject of temporary is not a constant expression}}907 static_assert(f()[0] == 1); // Ok908#endif909 910 constexpr int f2(int *x =(int[]){1,2,3}) {911 return x[0];912 }913 // Should evaluate to 1?914 constexpr int g = f2(); // #g_decl915 static_assert(g == 1, "");916 917 // This example should be rejected because the lifetime of the compound918 // literal assigned into x is that of the full expression, which is the919 // parenthesized assignment operator. So the return statement is using a920 // dangling pointer. FIXME: the note saying it's a read of a dereferenced921 // null pointer suggests we're doing something odd during constant expression922 // evaluation: I think it's still taking 'x' as being null from the call to923 // f3() rather than tracking the assignment happening in the VLA.924 constexpr int f3(int *x, int (*y)[*(x=(int[]){1,2,3})]) { // both-warning {{object backing the pointer 'x' will be destroyed at the end of the full-expression}}925 return x[0]; // both-note {{read of dereferenced null pointer is not allowed in a constant expression}}926 }927 constexpr int h = f3(0,0); // both-error {{constexpr variable 'h' must be initialized by a constant expression}} \928 both-note {{in call to 'f3(nullptr, nullptr)'}}929}930 931namespace TypeTraits {932 static_assert(__is_trivial(int), "");933 static_assert(__is_trivial(float), "");934 static_assert(__is_trivial(E), "");935 struct S{};936 static_assert(__is_trivial(S), "");937 struct S2 {938 S2() {}939 };940 static_assert(!__is_trivial(S2), "");941 942 template <typename T>943 struct S3 {944 constexpr bool foo() const { return __is_trivial(T); }945 };946 struct T {947 ~T() {}948 };949 struct U {};950 static_assert(S3<U>{}.foo(), "");951 static_assert(!S3<T>{}.foo(), "");952 953 typedef int Int;954 typedef Int IntAr[10];955 typedef const IntAr ConstIntAr;956 typedef ConstIntAr ConstIntArAr[4];957 958 static_assert(__array_rank(IntAr) == 1, "");959 static_assert(__array_rank(ConstIntArAr) == 2, "");960 961 static_assert(__array_extent(IntAr, 0) == 10, "");962 static_assert(__array_extent(ConstIntArAr, 0) == 4, "");963 static_assert(__array_extent(ConstIntArAr, 1) == 10, "");964}965 966#if __cplusplus >= 201402L967namespace SomeNS {968 using MyInt = int;969}970 971constexpr int ignoredDecls() {972 static_assert(true, "");973 struct F { int a; };974 enum E { b };975 using A = int;976 typedef int Z;977 namespace NewNS = SomeNS;978 using NewNS::MyInt;979 980 return F{12}.a;981}982static_assert(ignoredDecls() == 12, "");983 984namespace DiscardExprs {985#pragma clang diagnostic push986#pragma clang diagnostic ignored "-Wunused-value"987 typedef struct _GUID {988 __UINT32_TYPE__ Data1;989 __UINT16_TYPE__ Data2;990 __UINT16_TYPE__ Data3;991 __UINT8_TYPE__ Data4[8];992 } GUID;993 class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) GuidType;994 995 struct A{ int a; };996 constexpr int ignoredExprs() {997 (void)(1 / 2);998 A a{12};999 a;1000 (void)a;1001 (a);1002 1003 /// Ignored MaterializeTemporaryExpr.1004 struct B{ const int &a; };1005 (void)B{12};1006 1007 (void)5, (void)6;1008 1009 1 ? 0 : 1;1010 __is_trivial(int);1011 1012 (int){1};1013 (int[]){1,2,3};1014 int arr[] = {1,2,3};1015 arr[0];1016 "a";1017 'b';1018 sizeof(int);1019 alignof(int);1020 1021 (short)5;1022 (bool)1;1023 __null;1024 __builtin_offsetof(A, a);1025 1,2;1026 (int)1.0;1027 (float)1;1028 (double)1.0f;1029 (signed)4u;1030 __uuidof(GuidType);1031 __uuidof(number); // both-error {{cannot call operator __uuidof on a type with no GUID}}1032 1033 requires{false;};1034 constexpr int *p = nullptr;1035 p - p;1036 1037 return 0;1038 }1039 static_assert(ignoredExprs() == 0, "");1040 1041 constexpr int oh_my(int x) {1042 (int){ x++ };1043 return x;1044 }1045 static_assert(oh_my(0) == 1, "");1046 1047 constexpr int oh_my2(int x) {1048 int y{x++};1049 return x;1050 }1051 1052 static_assert(oh_my2(0) == 1, "");1053 1054 1055 /// Ignored comma expressions still have their1056 /// expressions evaluated.1057 constexpr int Comma(int start) {1058 int i = start;1059 1060 (void)i++;1061 (void)i++,(void)i++;1062 return i;1063 }1064 constexpr int Value = Comma(5);1065 static_assert(Value == 8, "");1066 1067 /// Ignored MemberExprs need to still evaluate the Base1068 /// expr.1069 constexpr A callme(int &i) {1070 ++i;1071 return A{};1072 }1073 constexpr int ignoredMemberExpr() {1074 int i = 0;1075 callme(i).a;1076 return i;1077 }1078 static_assert(ignoredMemberExpr() == 1, "");1079 1080 template <int I>1081 constexpr int foo() {1082 I;1083 return I;1084 }1085 static_assert(foo<3>() == 3, "");1086 1087 struct ATemp {1088 consteval ATemp ret_a() const { return ATemp{}; }1089 };1090 1091 void test() {1092 int k = (ATemp().ret_a(), 0);1093 }1094 1095#pragma clang diagnostic pop1096}1097#endif1098 1099namespace PredefinedExprs {1100#if __cplusplus >= 201402L1101 template<typename CharT>1102 constexpr bool strings_match(const CharT *str1, const CharT *str2) {1103 while (*str1 && *str2) {1104 if (*str1++ != *str2++)1105 return false;1106 };1107 1108 return *str1 == *str2;1109 }1110 1111 void foo() {1112 static_assert(strings_match(__FUNCSIG__, "void __cdecl PredefinedExprs::foo(void)"), "");1113 static_assert(strings_match(L__FUNCSIG__, L"void __cdecl PredefinedExprs::foo(void)"), "");1114 static_assert(strings_match(L__FUNCTION__, L"foo"), "");1115 static_assert(strings_match(__FUNCTION__, "foo"), "");1116 static_assert(strings_match(__func__, "foo"), "");1117 static_assert(strings_match(__PRETTY_FUNCTION__, "void PredefinedExprs::foo()"), "");1118 }1119 1120 constexpr char heh(unsigned index) {1121 __FUNCTION__; // both-warning {{result unused}}1122 __extension__ __FUNCTION__; // both-warning {{result unused}}1123 return __FUNCTION__[index];1124 }1125 static_assert(heh(0) == 'h', "");1126 static_assert(heh(1) == 'e', "");1127 static_assert(heh(2) == 'h', "");1128#endif1129}1130 1131namespace NE {1132 constexpr int foo() noexcept {1133 return 1;1134 }1135 static_assert(noexcept(foo()), "");1136 constexpr int foo2() {1137 return 1;1138 }1139 static_assert(!noexcept(foo2()), "");1140 1141#if __cplusplus > 201402L1142 constexpr int a() {1143 int b = 0;1144 (void)noexcept(++b); // both-warning {{expression with side effects has no effect in an unevaluated context}}1145 1146 return b;1147 }1148 static_assert(a() == 0, "");1149#endif1150}1151 1152namespace PointerCasts {1153 constexpr int M = 10;1154 constexpr const int *P = &M;1155 constexpr intptr_t A = (intptr_t)P; // both-error {{must be initialized by a constant expression}} \1156 // both-note {{cast that performs the conversions of a reinterpret_cast}}1157 1158 int array[(intptr_t)(char*)0]; // both-warning {{variable length array folded to constant array}}1159}1160 1161namespace InvalidDeclRefs {1162 bool b00; // both-note {{declared here}}1163 static_assert(b00, ""); // both-error {{not an integral constant expression}} \1164 // both-note {{read of non-const variable}}1165 1166 float b01; // both-note {{declared here}}1167 static_assert(b01, ""); // both-error {{not an integral constant expression}} \1168 // both-note {{read of non-constexpr variable}}1169 1170 extern const int b02; // both-note {{declared here}}1171 static_assert(b02, ""); // both-error {{not an integral constant expression}} \1172 // both-note {{initializer of 'b02' is unknown}}1173 1174 int b03 = 3; // both-note {{declared here}}1175 static_assert(b03, ""); // both-error {{not an integral constant expression}} \1176 // both-note {{read of non-const variable}}1177 1178 extern int var;1179 constexpr int *varp = &var; // Ok.1180}1181 1182namespace NonConstReads {1183 void *p = nullptr; // both-note {{declared here}}1184 static_assert(!p, ""); // both-error {{not an integral constant expression}} \1185 // both-note {{read of non-constexpr variable 'p'}}1186 1187 int arr[!p]; // both-error {{variable length array}}1188 1189 int z; // both-note {{declared here}}1190 static_assert(z == 0, ""); // both-error {{not an integral constant expression}} \1191 // both-note {{read of non-const variable 'z'}}1192}1193 1194/// This test passes a MaterializedTemporaryExpr to evaluateAsRValue.1195/// That needs to return a null pointer after the lvalue-to-rvalue conversion.1196/// We used to fail to do that.1197namespace rdar8769025 {1198 __attribute__((nonnull)) void f1(int * const &p);1199 void test_f1() {1200 f1(0); // both-warning{{null passed to a callee that requires a non-null argument}}1201 }1202}1203 1204namespace nullptrsub {1205 void a() {1206 char *f = (char *)0;1207 f = (char *)((char *)0 - (char *)0);1208 }1209}1210 1211namespace incdecbool {1212#if __cplusplus >= 201402L1213 constexpr bool incb(bool c) {1214 if (!c)1215 ++c;1216 else {++c; c++; }1217#if __cplusplus >= 202002L1218 // both-error@-3 {{ISO C++17 does not allow incrementing expression of type bool}}1219 // both-error@-3 2{{ISO C++17 does not allow incrementing expression of type bool}}1220#else1221 // both-warning@-6 {{incrementing expression of type bool is deprecated and incompatible with C++17}}1222#endif1223 return c;1224 }1225 static_assert(incb(false), "");1226 static_assert(incb(true), "");1227 static_assert(incb(true) == 1, "");1228#endif1229 1230 1231#if __cplusplus == 201103L1232 constexpr bool foo() { // both-error {{never produces a constant expression}}1233 bool b = true; // both-warning {{variable declaration in a constexpr function is a C++14 extension}}1234 b++; // both-warning {{incrementing expression of type bool is deprecated and incompatible with C++17}} \1235 // both-warning {{use of this statement in a constexpr function is a C++14 extension}} \1236 // both-note 2{{subexpression not valid in a constant expression}}1237 1238 return b;1239 }1240 static_assert(foo() == 1, ""); // both-error {{not an integral constant expression}} \1241 // both-note {{in call to}}1242#endif1243 1244 1245 1246}1247 1248#if __cplusplus >= 201402L1249constexpr int externvar1() { // both-error {{never produces a constant expression}}1250 extern char arr[]; // both-note {{declared here}}1251 return arr[0]; // both-note {{read of non-constexpr variable 'arr'}}1252}1253namespace externarr {1254 extern int arr[];1255 constexpr int *externarrindex = &arr[0]; /// No diagnostic.1256}1257 1258 1259namespace StmtExprs {1260 constexpr int foo() {1261 ({1262 int i;1263 for (i = 0; i < 76; i++) {}1264 i; // both-warning {{expression result unused}}1265 });1266 return 76;1267 }1268 static_assert(foo() == 76, "");1269 1270 namespace CrossFuncLabelDiff {1271 constexpr long a(bool x) { return x ? 0 : (intptr_t)&&lbl + (0 && ({lbl: 0;})); }1272 }1273 1274 /// GCC agrees with the bytecode interpreter here.1275 void switchInSE() {1276 static_assert(({ // ref-error {{not an integral constant expression}}1277 int i = 20;1278 switch(10) {1279 case 10: i = 300; // ref-note {{a constant expression cannot modify an object that is visible outside that expression}}1280 }1281 i;1282 }) == 300);1283 }1284}1285#endif1286 1287namespace Extern {1288 constexpr extern char Oops = 1;1289 static_assert(Oops == 1, "");1290 1291#if __cplusplus >= 201402L1292 struct NonLiteral {1293 NonLiteral() {}1294 };1295 NonLiteral nl;1296 constexpr NonLiteral &ExternNonLiteralVarDecl() {1297 extern NonLiteral nl;1298 return nl;1299 }1300 static_assert(&ExternNonLiteralVarDecl() == &nl, "");1301#endif1302 1303 struct A {1304 int b;1305 };1306 1307 extern constexpr A a{12};1308 static_assert(a.b == 12, "");1309}1310 1311#if __cplusplus >= 201402L1312constexpr int StmtExprEval() {1313 if (({1314 while (0);1315 true;1316 })) {1317 return 2;1318 }1319 return 1;1320}1321static_assert(StmtExprEval() == 2, "");1322 1323constexpr int ReturnInStmtExpr() { // both-error {{never produces a constant expression}}1324 return ({1325 return 1; // both-note 2{{this use of statement expressions is not supported in a constant expression}}1326 2;1327 });1328}1329static_assert(ReturnInStmtExpr() == 1, ""); // both-error {{not an integral constant expression}} \1330 // both-note {{in call to}}1331 1332#endif1333 1334namespace ComparisonAgainstOnePastEnd {1335 int a, b;1336 static_assert(&a + 1 == &b, ""); // both-error {{not an integral constant expression}} \1337 // both-note {{comparison against pointer '&a + 1' that points past the end of a complete object has unspecified value}}1338 static_assert(&a == &b + 1, ""); // both-error {{not an integral constant expression}} \1339 // both-note {{comparison against pointer '&b + 1' that points past the end of a complete object has unspecified value}}1340 1341 static_assert(&a + 1 == &b + 1, ""); // both-error {{static assertion failed}}1342};1343 1344namespace NTTP {1345 template <typename _Tp, unsigned _Nm>1346 constexpr unsigned1347 size(const _Tp (&)[_Nm]) noexcept1348 { return _Nm; }1349 1350 template <char C>1351 static int write_padding() {1352 static const char Chars[] = {C};1353 1354 return size(Chars);1355 }1356}1357 1358#if __cplusplus >= 201402L1359namespace UnaryOpError {1360 constexpr int foo() {1361 int f = 0;1362 ++g; // both-error {{use of undeclared identifier 'g'}} \1363 both-error {{cannot assign to variable 'g' with const-qualified type 'const int'}} \1364 both-note@#g_decl {{'CompoundLiterals::g' declared here}} \1365 both-note@#g_decl {{variable 'g' declared const here}}1366 return f;1367 }1368}1369#endif1370 1371namespace VolatileReads {1372 const volatile int b = 1;1373 static_assert(b, ""); // both-error {{not an integral constant expression}} \1374 // both-note {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}1375 1376 1377 constexpr int a = 12;1378 constexpr volatile int c = (volatile int&)a; // both-error {{must be initialized by a constant expression}} \1379 // both-note {{read of volatile-qualified type 'volatile int'}}1380 1381 volatile constexpr int n1 = 0; // both-note {{here}}1382 volatile const int n2 = 0; // both-note {{here}}1383 constexpr int m1 = n1; // both-error {{constant expression}} \1384 // both-note {{read of volatile-qualified type 'const volatile int'}}1385 constexpr int m2 = n2; // both-error {{constant expression}} \1386 // both-note {{read of volatile-qualified type 'const volatile int'}}1387 constexpr int m1b = const_cast<const int&>(n1); // both-error {{constant expression}} \1388 // both-note {{read of volatile object 'n1'}}1389 constexpr int m2b = const_cast<const int&>(n2); // both-error {{constant expression}} \1390 // both-note {{read of volatile object 'n2'}}1391 1392 struct S {1393 constexpr S(int=0) : i(1) {}1394 int i;1395 };1396 constexpr volatile S vs; // both-note {{here}}1397 static_assert(const_cast<int&>(vs.i), ""); // both-error {{constant expression}} \1398 // both-note {{read of volatile object 'vs'}}1399}1400#if __cplusplus >= 201703L1401namespace {1402 struct C {1403 int x;1404 };1405 1406 template <const C *p> void f() {1407 const auto &[c] = *p;1408 &c; // both-warning {{expression result unused}}1409 }1410}1411#endif1412 1413void localConstexpr() {1414 constexpr int a = 1/0; // both-error {{must be initialized by a constant expression}} \1415 // both-note {{division by zero}} \1416 // both-warning {{division by zero is undefined}} \1417 // both-note {{declared here}}1418 static_assert(a == 0, ""); // both-error {{not an integral constant expression}} \1419 // both-note {{initializer of 'a' is not a constant expression}}1420}1421 1422namespace Foo {1423 namespace Bar {1424 constexpr int FB = 10;1425 }1426}1427constexpr int usingDirectiveDecl() {1428 using namespace Foo::Bar;1429 return FB;1430}1431static_assert(usingDirectiveDecl() == 10, "");1432 1433namespace OnePastEndCmp {1434 struct S {1435 int a;1436 int b;1437 };1438 1439 constexpr S s{12,13};1440 constexpr const int *p = &s.a;1441 constexpr const int *q = &s.a + 1;1442 static_assert(p != q, "");1443}1444 1445namespace ExternRedecl {1446 extern const int a;1447 constexpr const int *p = &a;1448 constexpr int a = 10;1449 static_assert(*p == 10, "");1450}1451