126 lines · cpp
1// RUN: %clang_cc1 -triple x86_64 -fcxx-exceptions -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s2// RUN: %clang_cc1 -triple x86_64 -fcxx-exceptions -std=c++20 -verify=ref,both %s3 4namespace Throw {5 6 constexpr int ConditionalThrow(bool t) {7 if (t)8 throw 4; // both-note {{subexpression not valid in a constant expression}}9 10 return 0;11 }12 13 static_assert(ConditionalThrow(false) == 0, "");14 static_assert(ConditionalThrow(true) == 0, ""); // both-error {{not an integral constant expression}} \15 // both-note {{in call to 'ConditionalThrow(true)'}}16 17 constexpr int Throw() { // both-error {{never produces a constant expression}}18 throw 5; // both-note {{subexpression not valid in a constant expression}}19 return 0;20 }21 22 constexpr int NoSubExpr() { // both-error {{never produces a constant expression}}23 throw; // both-note 2{{subexpression not valid}}24 return 0;25 }26 static_assert(NoSubExpr() == 0, ""); // both-error {{not an integral constant expression}} \27 // both-note {{in call to}}28}29 30namespace Asm {31 constexpr int ConditionalAsm(bool t) {32 if (t)33 asm(""); // both-note {{subexpression not valid in a constant expression}}34 35 return 0;36 }37 static_assert(ConditionalAsm(false) == 0, "");38 static_assert(ConditionalAsm(true) == 0, ""); // both-error {{not an integral constant expression}} \39 // both-note {{in call to 'ConditionalAsm(true)'}}40 41 42 constexpr int Asm() { // both-error {{never produces a constant expression}}43 __asm volatile(""); // both-note {{subexpression not valid in a constant expression}}44 return 0;45 }46}47 48namespace Casts {49 constexpr int a = reinterpret_cast<int>(12); // both-error {{must be initialized by a constant expression}} \50 // both-note {{reinterpret_cast is not allowed}}51 52 void func() {53 struct B {};54 B b;55 (void)*reinterpret_cast<void*>(&b); // both-error {{indirection not permitted on operand of type 'void *'}}56 }57 58 /// Just make sure this doesn't crash.59 float PR9558 = reinterpret_cast<const float&>("asd");60}61 62 63/// This used to crash in collectBlock().64struct S {65};66S s;67S *sp[2] = {&s, &s};68S *&spp = sp[1];69 70namespace InvalidBitCast {71 void foo() {72 const long long int i = 1; // both-note {{declared const here}}73 if (*(double *)&i == 2) {74 i = 0; // both-error {{cannot assign to variable}}75 }76 }77 78 struct S2 {79 void *p;80 };81 struct T {82 S2 s;83 };84 constexpr T t = {{nullptr}};85 constexpr void *foo2() { return ((void **)&t)[0]; } // both-error {{never produces a constant expression}} \86 // both-note 2{{cast that performs the conversions of a reinterpret_cast}}87 constexpr auto x = foo2(); // both-error {{must be initialized by a constant expression}} \88 // both-note {{in call to}}89 90 91 struct sockaddr92 {93 char sa_data[8];94 };95 struct in_addr96 {97 unsigned int s_addr;98 };99 struct sockaddr_in100 {101 unsigned short int sin_port;102 struct in_addr sin_addr;103 };104 /// Bitcast from sockaddr to sockaddr_in. Used to crash.105 unsigned int get_addr(sockaddr addr) {106 return ((sockaddr_in *)&addr)->sin_addr.s_addr;107 }108 109 110 struct s { int a; int b[1]; };111 struct s myx;112 int *myy = ((struct s *)&myx.a)->b;113}114 115namespace InvalidIntPtrRecord {116 typedef __SIZE_TYPE__ Size_t;117 118#define bufsize ((1LL << (8 * sizeof(Size_t) - 2)) - 256)119 120 struct S {121 short buf[bufsize]; // both-error {{array is too large}}122 int a;123 };124 Size_t foo() { return (Size_t)(&((struct S *)0)->a); }125}126