xref: /llvm-project/clang/test/AST/ByteCode/constexpr.c (revision e8674af6f41b2e78ceebabb23e40588c41da5a23)
18079a2c5Syronglin // RUN: %clang_cc1 -std=c23 -verify=ref,both -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -Wno-div-by-zero %s
28079a2c5Syronglin // RUN: %clang_cc1 -std=c23 -verify=expected,both -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -Wno-div-by-zero -fexperimental-new-constant-interpreter %s
38079a2c5Syronglin 
48079a2c5Syronglin // Check that constexpr only applies to variables.
58079a2c5Syronglin constexpr void f0() {} // both-error {{'constexpr' can only be used in variable declarations}}
68079a2c5Syronglin constexpr const int f1() { return 0; } // both-error {{'constexpr' can only be used in variable declarations}}
78079a2c5Syronglin 
88079a2c5Syronglin constexpr struct S1 { int f; }; //both-error {{struct cannot be marked constexpr}}
98079a2c5Syronglin constexpr struct S2 ; // both-error {{struct cannot be marked constexpr}}
108079a2c5Syronglin constexpr union U1; // both-error {{union cannot be marked constexpr}}
118079a2c5Syronglin constexpr union U2 {int a; float b;}; // both-error {{union cannot be marked constexpr}}
128079a2c5Syronglin constexpr enum E1 {A = 1, B = 2} ; // both-error {{enum cannot be marked constexpr}}
138079a2c5Syronglin struct S3 {
148079a2c5Syronglin   static constexpr int f = 0; // both-error {{type name does not allow storage class}}
158079a2c5Syronglin   // both-error@-1 {{type name does not allow constexpr}}
168079a2c5Syronglin   // both-error@-2 {{expected ';' at end}}
178079a2c5Syronglin   constexpr int f1 = 0;
188079a2c5Syronglin   // both-error@-1 {{type name does not allow constexpr}}
198079a2c5Syronglin   // both-error@-2 {{expected ';' at end}}
208079a2c5Syronglin };
218079a2c5Syronglin 
228079a2c5Syronglin constexpr; // both-error {{'constexpr' can only be used in variable declarations}}
238079a2c5Syronglin constexpr int V1 = 3;
248079a2c5Syronglin constexpr float V2 = 7.0;
258079a2c5Syronglin int V3 = (constexpr)3; // both-error {{expected expression}}
268079a2c5Syronglin 
278079a2c5Syronglin void f2() {
288079a2c5Syronglin   constexpr int a = 0;
298079a2c5Syronglin   constexpr float b = 1.7f;
308079a2c5Syronglin }
318079a2c5Syronglin 
328079a2c5Syronglin // Check how constexpr works with other storage-class specifiers.
338079a2c5Syronglin constexpr auto V4 = 1;
348079a2c5Syronglin constexpr static auto V5 = 1;
358079a2c5Syronglin constexpr static const auto V6 = 1;
368079a2c5Syronglin constexpr static const int V7 = 1;
378079a2c5Syronglin constexpr static int V8 = 1;
388079a2c5Syronglin constexpr auto Ulong = 1L;
398079a2c5Syronglin constexpr auto CompoundLiteral = (int){13};
408079a2c5Syronglin constexpr auto DoubleCast = (double)(1 / 3);
418079a2c5Syronglin constexpr auto String = "this is a string"; // both-error {{constexpr pointer initializer is not null}}
428079a2c5Syronglin constexpr signed auto Long = 1L; // both-error {{'auto' cannot be signed or unsigned}}
438079a2c5Syronglin _Static_assert(_Generic(Ulong, long : 1));
448079a2c5Syronglin _Static_assert(_Generic(CompoundLiteral, int : 1));
458079a2c5Syronglin _Static_assert(_Generic(DoubleCast, double : 1));
468079a2c5Syronglin _Static_assert(_Generic(String, char* : 1));
478079a2c5Syronglin 
488079a2c5Syronglin typedef constexpr int Foo; // both-error {{typedef cannot be constexpr}}
498079a2c5Syronglin constexpr typedef int Bar; // both-error {{typedef cannot be constexpr}}
508079a2c5Syronglin 
518079a2c5Syronglin void f3(constexpr register int P1) { // both-error {{function parameter cannot be constexpr}}
528079a2c5Syronglin   constexpr register int V9 = 0;
538079a2c5Syronglin   constexpr register auto V10 = 0.0;
548079a2c5Syronglin }
558079a2c5Syronglin 
568079a2c5Syronglin constexpr thread_local int V11 = 38; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}
578079a2c5Syronglin constexpr static thread_local double V12 = 38; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}
588079a2c5Syronglin constexpr extern thread_local char V13; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}
598079a2c5Syronglin // both-error@-1 {{cannot combine with previous 'extern' declaration specifier}}
608079a2c5Syronglin // both-error@-2 {{constexpr variable declaration must be a definition}}
618079a2c5Syronglin constexpr thread_local short V14 = 38; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}
628079a2c5Syronglin 
638079a2c5Syronglin // Check how constexpr works with qualifiers.
648079a2c5Syronglin constexpr _Atomic int V15 = 0; // both-error {{constexpr variable cannot have type 'const _Atomic(int)'}}
658079a2c5Syronglin constexpr _Atomic(int) V16 = 0; // both-error {{constexpr variable cannot have type 'const _Atomic(int)'}}
668079a2c5Syronglin 
678079a2c5Syronglin constexpr volatile int V17 = 0; // both-error {{constexpr variable cannot have type 'const volatile int'}}
688079a2c5Syronglin 
698079a2c5Syronglin constexpr int * restrict V18 = 0; // both-error {{constexpr variable cannot have type 'int *const restrict'}}
708079a2c5Syronglin 
718079a2c5Syronglin constexpr extern char Oops = 1; // both-error {{cannot combine with previous 'extern' declaration specifier}} \
728079a2c5Syronglin                                 // both-warning {{'extern' variable has an initializer}}
738079a2c5Syronglin 
748079a2c5Syronglin constexpr int * restrict * Oops1 = 0;
758079a2c5Syronglin 
768079a2c5Syronglin typedef _Atomic(int) TheA;
778079a2c5Syronglin typedef volatile short TheV;
788079a2c5Syronglin typedef float * restrict TheR;
798079a2c5Syronglin 
808079a2c5Syronglin constexpr TheA V19[3] = {};
818079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'const TheA[3]' (aka 'const _Atomic(int)[3]')}}
828079a2c5Syronglin constexpr TheV V20[3] = {};
838079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'const TheV[3]' (aka 'const volatile short[3]')}}
848079a2c5Syronglin constexpr TheR V21[3] = {};
858079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'const TheR[3]' (aka 'float *restrict const[3]')}}
868079a2c5Syronglin 
878079a2c5Syronglin struct HasA {
888079a2c5Syronglin   TheA f;
898079a2c5Syronglin   int b;
908079a2c5Syronglin };
918079a2c5Syronglin 
928079a2c5Syronglin struct HasV {
938079a2c5Syronglin   float b;
948079a2c5Syronglin   TheV f;
958079a2c5Syronglin };
968079a2c5Syronglin 
978079a2c5Syronglin struct HasR {
988079a2c5Syronglin   short b;
998079a2c5Syronglin   int a;
1008079a2c5Syronglin   TheR f;
1018079a2c5Syronglin };
1028079a2c5Syronglin 
1038079a2c5Syronglin constexpr struct HasA V22[2] = {};
1048079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}
1058079a2c5Syronglin constexpr struct HasV V23[2] = {};
1068079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'TheV' (aka 'volatile short')}}
1078079a2c5Syronglin constexpr struct HasR V24[2] = {};
1088079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'TheR' (aka 'float *restrict')}}
1098079a2c5Syronglin 
1108079a2c5Syronglin union U3 {
1118079a2c5Syronglin   float a;
1128079a2c5Syronglin   union {
1138079a2c5Syronglin     struct HasA f;
1148079a2c5Syronglin     struct HasR f1;
1158079a2c5Syronglin   };
1168079a2c5Syronglin };
1178079a2c5Syronglin 
1188079a2c5Syronglin constexpr union U3 V25 = {};
1198079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}
1208079a2c5Syronglin constexpr union U3 V26[8] = {};
1218079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}
1228079a2c5Syronglin 
1238079a2c5Syronglin struct S4 {
1248079a2c5Syronglin   union U3 f[3];
1258079a2c5Syronglin };
1268079a2c5Syronglin 
1278079a2c5Syronglin constexpr struct S4 V27 = {};
1288079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}
1298079a2c5Syronglin constexpr const int V28 = 28;
1308079a2c5Syronglin 
1318079a2c5Syronglin struct S {
1328079a2c5Syronglin   union {
1338079a2c5Syronglin     volatile int i;
1348079a2c5Syronglin   };
1358079a2c5Syronglin   int j;
1368079a2c5Syronglin };
1378079a2c5Syronglin 
1388079a2c5Syronglin constexpr struct S s = {}; // both-error {{constexpr variable cannot have type 'volatile int'}}
1398079a2c5Syronglin 
1408079a2c5Syronglin // Check that constexpr variable must have a valid initializer which is a
1418079a2c5Syronglin // constant expression.
1428079a2c5Syronglin constexpr int V29;
1438079a2c5Syronglin // both-error@-1 {{constexpr variable 'V29' must be initialized by a constant expression}}
1448079a2c5Syronglin 
1458079a2c5Syronglin struct S5 {
1468079a2c5Syronglin   int f;
1478079a2c5Syronglin };
1488079a2c5Syronglin 
1498079a2c5Syronglin constexpr struct S5 V30;
1508079a2c5Syronglin // both-error@-1 {{constexpr variable 'V30' must be initialized by a constant expression}}
1518079a2c5Syronglin constexpr struct S5 V31 = {};
1528079a2c5Syronglin 
1538079a2c5Syronglin int randomFoo() { return 7; }
1548079a2c5Syronglin 
1558079a2c5Syronglin constexpr float V32 = randomFoo();
1568079a2c5Syronglin // both-error@-1 {{constexpr variable 'V32' must be initialized by a constant expression}}
1578079a2c5Syronglin 
1588079a2c5Syronglin const int V33 = 4;
1598079a2c5Syronglin const int V34 = 0;
1608079a2c5Syronglin const int V35 = 2;
1618079a2c5Syronglin 
1628079a2c5Syronglin constexpr int V36 = V33 / V34;
1638079a2c5Syronglin // both-error@-1 {{constexpr variable 'V36' must be initialized by a constant expression}}
1648079a2c5Syronglin constexpr int V37 = V33 / V35;
1658079a2c5Syronglin // both-error@-1 {{constexpr variable 'V37' must be initialized by a constant expression}}
1668079a2c5Syronglin constexpr int V38 = 3;
1678079a2c5Syronglin constexpr int V39 = V38 / V38;
1688079a2c5Syronglin constexpr int V40 = V38 / 2;
1698079a2c5Syronglin constexpr int V41 = V38 / 0;
1708079a2c5Syronglin // both-error@-1 {{constexpr variable 'V41' must be initialized by a constant expression}}
1718079a2c5Syronglin // both-note@-2 {{division by zero}}
1728079a2c5Syronglin constexpr int V42 = V38 & 0;
1738079a2c5Syronglin 
1748079a2c5Syronglin constexpr struct S5 V43 = { randomFoo() };
1758079a2c5Syronglin // both-error@-1 {{constexpr variable 'V43' must be initialized by a constant expression}}
1768079a2c5Syronglin constexpr struct S5 V44 = { 0 };
1778079a2c5Syronglin constexpr struct S5 V45 = { V38 / 0 };
1788079a2c5Syronglin // both-error@-1 {{constexpr variable 'V45' must be initialized by a constant expression}}
1798079a2c5Syronglin // both-note@-2 {{division by zero}}
1808079a2c5Syronglin 
1818079a2c5Syronglin constexpr float V46[3] = {randomFoo() };
1828079a2c5Syronglin // both-error@-1 {{constexpr variable 'V46' must be initialized by a constant expression}}
1838079a2c5Syronglin constexpr struct S5 V47[3] = {randomFoo() };
1848079a2c5Syronglin // both-error@-1 {{constexpr variable 'V47' must be initialized by a constant expression}}
1858079a2c5Syronglin 
1868079a2c5Syronglin const static int V48 = V38;
1878079a2c5Syronglin constexpr static int V49 = V48;
1888079a2c5Syronglin // both-error@-1 {{constexpr variable 'V49' must be initialized by a constant expression}}
1898079a2c5Syronglin 
1908079a2c5Syronglin void f4(const int P1) {
1918079a2c5Syronglin   constexpr int V = P1;
1928079a2c5Syronglin // both-error@-1 {{constexpr variable 'V' must be initialized by a constant expression}}
1938079a2c5Syronglin 
1948079a2c5Syronglin   constexpr int V1 = 12;
1958079a2c5Syronglin   constexpr const int *V2 = &V1;
1968079a2c5Syronglin // both-error@-1 {{constexpr variable 'V2' must be initialized by a constant expression}}
1978079a2c5Syronglin }
1988079a2c5Syronglin 
1998079a2c5Syronglin // Check that initializer for constexpr variable should match the type of the
2008079a2c5Syronglin // variable and is exactly representable int the variable's type.
2018079a2c5Syronglin 
2028079a2c5Syronglin struct S6 {
2038079a2c5Syronglin   unsigned char a;
2048079a2c5Syronglin };
2058079a2c5Syronglin 
2068079a2c5Syronglin struct S7 {
2078079a2c5Syronglin   union {
2088079a2c5Syronglin     float a;
2098079a2c5Syronglin   };
2108079a2c5Syronglin   unsigned int b;
2118079a2c5Syronglin };
2128079a2c5Syronglin 
2138079a2c5Syronglin struct S8 {
2148079a2c5Syronglin   unsigned char a[3];
2158079a2c5Syronglin   unsigned int b[3];
2168079a2c5Syronglin };
2178079a2c5Syronglin 
2188079a2c5Syronglin constexpr struct S8 DesigInit = {.b = {299, 7, 8}, .a = {-1, 7, 8}};
2198079a2c5Syronglin // both-error@-1 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'unsigned char'}}
2208079a2c5Syronglin 
2218079a2c5Syronglin void f5() {
2228079a2c5Syronglin   constexpr char V50 = 300;
2238079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 300 which is not exactly representable in type 'const char'}}
2248079a2c5Syronglin   constexpr float V51 = 1.0 / 3.0;
2258079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 3.333333e-01 which is not exactly representable in type 'const float'}}
2268079a2c5Syronglin   constexpr float V52 = 0.7;
2278079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 7.000000e-01 which is not exactly representable in type 'const float'}}
2288079a2c5Syronglin   constexpr float V53 = 1.0f / 3.0f;
2298079a2c5Syronglin   constexpr float V54 = 432000000000;
2308079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 432000000000 which is not exactly representable in type 'const float'}}
2318079a2c5Syronglin   constexpr unsigned char V55[] = {
2328079a2c5Syronglin       "\xAF",
2338079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to -81 which is not exactly representable in type 'const unsigned char'}}
2348079a2c5Syronglin   };
2358079a2c5Syronglin 
2368079a2c5Syronglin   constexpr unsigned char V56[] = {
2378079a2c5Syronglin       u8"\xAF",
2388079a2c5Syronglin   };
2398079a2c5Syronglin   constexpr struct S6 V57 = {299};
2408079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 299 which is not exactly representable in type 'unsigned char'}}
2418079a2c5Syronglin   constexpr struct S6 V58 = {-299};
2428079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to -299 which is not exactly representable in type 'unsigned char'}}
2438079a2c5Syronglin   constexpr double V59 = 0.5;
2448079a2c5Syronglin   constexpr double V60 = 1.0;
2458079a2c5Syronglin   constexpr float V61 = V59 / V60;
2468079a2c5Syronglin   constexpr double V62 = 1.7;
2478079a2c5Syronglin   constexpr float V63 = V59 / V62;
2488079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 2.941176e-01 which is not exactly representable in type 'const float'}}
2498079a2c5Syronglin 
2508079a2c5Syronglin   constexpr unsigned char V64 = '\xAF';
2518079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to -81 which is not exactly representable in type 'const unsigned char'}}
2528079a2c5Syronglin   constexpr unsigned char V65 = u8'\xAF';
2538079a2c5Syronglin 
2548079a2c5Syronglin   constexpr char V66[3] = {300};
2558079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 300 which is not exactly representable in type 'const char'}}
2568079a2c5Syronglin   constexpr struct S6 V67[3] = {300};
2578079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 300 which is not exactly representable in type 'unsigned char'}}
2588079a2c5Syronglin 
2598079a2c5Syronglin   constexpr struct S7 V68 = {0.3, -1 };
2608079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 3.000000e-01 which is not exactly representable in type 'float'}}
2618079a2c5Syronglin   // both-error@-2 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'unsigned int'}}
2628079a2c5Syronglin   constexpr struct S7 V69 = {0.5, -1 };
2638079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'unsigned int'}}
2648079a2c5Syronglin   constexpr struct S7 V70[3] = {{123456789}};
2658079a2c5Syronglin   // both-error@-1 {{constexpr initializer evaluates to 123456789 which is not exactly representable in type 'float'}}
2668079a2c5Syronglin 
2678079a2c5Syronglin   constexpr int V71 = 0.3;
2688079a2c5Syronglin   // both-error@-1 {{constexpr initializer for type 'const int' is of type 'double'}}
2698079a2c5Syronglin   constexpr int V72 = V59;
2708079a2c5Syronglin   // both-error@-1 {{constexpr initializer for type 'const int' is of type 'const double'}}
2718079a2c5Syronglin   constexpr struct S6 V73 = {V59};
2728079a2c5Syronglin   // both-error@-1 {{constexpr initializer for type 'unsigned char' is of type 'const double'}}
2738079a2c5Syronglin 
2748079a2c5Syronglin   constexpr float V74 = 1;
2758079a2c5Syronglin   constexpr float V75 = V59;
2768079a2c5Syronglin   constexpr unsigned int V76[3] = {0.5};
2778079a2c5Syronglin   // both-error@-1 {{constexpr initializer for type 'const unsigned int' is of type 'double'}}
2788079a2c5Syronglin 
2798079a2c5Syronglin   constexpr _Complex float V77 = 0;
2808079a2c5Syronglin   constexpr float V78 = V77;
2818079a2c5Syronglin   // both-error@-1 {{constexpr initializer for type 'const float' is of type 'const _Complex float'}}
2828079a2c5Syronglin   constexpr int V79 = V77;
2838079a2c5Syronglin   // both-error@-1 {{constexpr initializer for type 'const int' is of type 'const _Complex float'}}
2848079a2c5Syronglin 
2858079a2c5Syronglin }
2868079a2c5Syronglin 
2878079a2c5Syronglin constexpr char string[] = "test""ing this out\xFF";
2888079a2c5Syronglin constexpr unsigned char ustring[] = "test""ing this out\xFF";
2898079a2c5Syronglin // both-error@-1 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'const unsigned char'}}
2908079a2c5Syronglin constexpr char u8string[] = u8"test"u8"ing this out\xFF";
2918079a2c5Syronglin // both-error@-1 {{constexpr initializer evaluates to 255 which is not exactly representable in type 'const char'}}
2928079a2c5Syronglin constexpr unsigned char u8ustring[] = u8"test"u8"ing this out\xFF";
2938079a2c5Syronglin constexpr unsigned short uustring[] = u"test"u"ing this out\xFF";
2948079a2c5Syronglin constexpr unsigned int Ustring[] = U"test"U"ing this out\xFF";
2958079a2c5Syronglin constexpr unsigned char Arr2[6][6] = {
2968079a2c5Syronglin   {"ek\xFF"}, {"ek\xFF"}
2978079a2c5Syronglin // both-error@-1 2{{constexpr initializer evaluates to -1 which is not exactly representable in type 'const unsigned char'}}
2988079a2c5Syronglin };
2998079a2c5Syronglin 
3008079a2c5Syronglin constexpr int i = (12);
3018079a2c5Syronglin constexpr int j = (i);
3028079a2c5Syronglin constexpr unsigned jneg = (-i);
3038079a2c5Syronglin // both-error@-1 {{constexpr initializer evaluates to -12 which is not exactly representable in type 'const unsigned int'}}
3048079a2c5Syronglin 
3058079a2c5Syronglin // Check that initializer for pointer constexpr variable should be null.
3068079a2c5Syronglin constexpr int V80 = 3;
3078079a2c5Syronglin constexpr const int *V81 = &V80;
3088079a2c5Syronglin // both-error@-1 {{constexpr pointer initializer is not null}}
3098079a2c5Syronglin constexpr int *V82 = 0;
3108079a2c5Syronglin constexpr int *V83 = V82;
3118079a2c5Syronglin constexpr int *V84 = 42;
312*e8674af6STimm Baeder // both-error@-1 {{constexpr variable 'V84' must be initialized by a constant expression}}
313*e8674af6STimm Baeder // both-note@-2 {{this conversion is not allowed in a constant expression}}
3148079a2c5Syronglin // both-error@-3 {{constexpr pointer initializer is not null}}
3158079a2c5Syronglin constexpr int *V85 = nullptr;
3168079a2c5Syronglin 
3178079a2c5Syronglin // Check that constexpr variables should not be VLAs.
3188079a2c5Syronglin void f6(const int P1) {
3198079a2c5Syronglin   constexpr int V86[P1] = {};
3208079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'const int[P1]'}}
3218079a2c5Syronglin   const int V87 = 3;
3228079a2c5Syronglin   constexpr int V88[V87] = {};
3238079a2c5Syronglin // both-warning@-1 {{variable length array folded to constant array as an extension}}
3248079a2c5Syronglin   int V89 = 7;
3258079a2c5Syronglin   constexpr int V90[V89] = {};
3268079a2c5Syronglin // both-error@-1 {{constexpr variable cannot have type 'const int[V89]'}}
3278079a2c5Syronglin }
3288079a2c5Syronglin 
3298079a2c5Syronglin void f7(int n, int array[n]) {
3308079a2c5Syronglin   constexpr typeof(array) foo = 0; // Accepted because array is a pointer type, not a VLA type
3318079a2c5Syronglin   int (*(*fp)(int n))[n];
3328079a2c5Syronglin   constexpr typeof(fp) bar = 0; // both-error {{constexpr variable cannot have type 'const typeof (fp)' (aka 'int (*(*const)(int))[n]')}}
3338079a2c5Syronglin }
3348079a2c5Syronglin 
3358079a2c5Syronglin // Check how constexpr works with NaNs and infinities.
3368079a2c5Syronglin #define FLT_NAN __builtin_nanf("1")
3378079a2c5Syronglin #define DBL_NAN __builtin_nan("1")
3388079a2c5Syronglin #define LD_NAN __builtin_nanf("1")
3398079a2c5Syronglin #define FLT_SNAN __builtin_nansf("1")
3408079a2c5Syronglin #define DBL_SNAN __builtin_nans("1")
3418079a2c5Syronglin #define LD_SNAN __builtin_nansl("1")
3428079a2c5Syronglin #define INF __builtin_inf()
3438079a2c5Syronglin void infsNaNs() {
3448079a2c5Syronglin   // Inf and quiet NaN is always fine, signaling NaN must have the same type.
3458079a2c5Syronglin   constexpr float fl0 = INF;
3468079a2c5Syronglin   constexpr float fl1 = (long double)INF;
3478079a2c5Syronglin   constexpr float fl2 = (long double)FLT_NAN;
3488079a2c5Syronglin   constexpr float fl3 = FLT_NAN;
3498079a2c5Syronglin   constexpr float fl5 = DBL_NAN;
3508079a2c5Syronglin   constexpr float fl6 = LD_NAN;
3518079a2c5Syronglin   constexpr float fl7 = DBL_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const float'}}
3528079a2c5Syronglin   constexpr float fl8 = LD_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const float'}}
3538079a2c5Syronglin 
3548079a2c5Syronglin   constexpr double db0 = FLT_NAN;
3558079a2c5Syronglin   constexpr double db2 = DBL_NAN;
3568079a2c5Syronglin   constexpr double db3 = DBL_SNAN;
3578079a2c5Syronglin   constexpr double db4 = FLT_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const double'}}
3588079a2c5Syronglin   constexpr double db5 = LD_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const double'}}
3598079a2c5Syronglin   constexpr double db6 = INF;
3608079a2c5Syronglin }
3618079a2c5Syronglin 
3628079a2c5Syronglin constexpr struct S9 s9 = {  }; // both-error {{variable has incomplete type 'const struct S9'}} \
3638079a2c5Syronglin                                // both-note {{forward declaration of 'struct S9'}}
3648079a2c5Syronglin 
3658079a2c5Syronglin struct S10 {
3668079a2c5Syronglin   signed long long i : 8;
3678079a2c5Syronglin };
3688079a2c5Syronglin constexpr struct S10 c = { 255 };
3698079a2c5Syronglin // FIXME-expected-error@-1 {{constexpr initializer evaluates to 255 which is not exactly representable in 'long long' bit-field with width 8}}
3708079a2c5Syronglin // See: GH#101299
371