brintos

brintos / llvm-project-archived public Read only

0
0
Text · 43.5 KiB · c6d79f9 Raw
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