brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.4 KiB · af96bf3 Raw
371 lines · c
1// RUN: %clang_cc1 -std=c23 -verify=ref,both -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -Wno-div-by-zero %s2// 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 %s3 4// Check that constexpr only applies to variables.5constexpr void f0() {} // both-error {{'constexpr' can only be used in variable declarations}}6constexpr const int f1() { return 0; } // both-error {{'constexpr' can only be used in variable declarations}}7 8constexpr struct S1 { int f; }; //both-error {{struct cannot be marked constexpr}}9constexpr struct S2 ; // both-error {{struct cannot be marked constexpr}}10constexpr union U1; // both-error {{union cannot be marked constexpr}}11constexpr union U2 {int a; float b;}; // both-error {{union cannot be marked constexpr}}12constexpr enum E1 {A = 1, B = 2} ; // both-error {{enum cannot be marked constexpr}}13struct S3 {14  static constexpr int f = 0; // both-error {{type name does not allow storage class}}15  // both-error@-1 {{type name does not allow constexpr}}16  // both-error@-2 {{expected ';' at end}}17  constexpr int f1 = 0;18  // both-error@-1 {{type name does not allow constexpr}}19  // both-error@-2 {{expected ';' at end}}20};21 22constexpr; // both-error {{'constexpr' can only be used in variable declarations}}23constexpr int V1 = 3;24constexpr float V2 = 7.0;25int V3 = (constexpr)3; // both-error {{expected expression}}26 27void f2() {28  constexpr int a = 0;29  constexpr float b = 1.7f;30}31 32// Check how constexpr works with other storage-class specifiers.33constexpr auto V4 = 1;34constexpr static auto V5 = 1;35constexpr static const auto V6 = 1;36constexpr static const int V7 = 1;37constexpr static int V8 = 1;38constexpr auto Ulong = 1L;39constexpr auto CompoundLiteral = (int){13};40constexpr auto DoubleCast = (double)(1 / 3);41constexpr auto String = "this is a string"; // both-error {{constexpr pointer initializer is not null}}42constexpr signed auto Long = 1L; // both-error {{'auto' cannot be signed or unsigned}}43_Static_assert(_Generic(Ulong, long : 1));44_Static_assert(_Generic(CompoundLiteral, int : 1));45_Static_assert(_Generic(DoubleCast, double : 1));46_Static_assert(_Generic(String, char* : 1));47 48typedef constexpr int Foo; // both-error {{typedef cannot be constexpr}}49constexpr typedef int Bar; // both-error {{typedef cannot be constexpr}}50 51void f3(constexpr register int P1) { // both-error {{function parameter cannot be constexpr}}52  constexpr register int V9 = 0;53  constexpr register auto V10 = 0.0;54}55 56constexpr thread_local int V11 = 38; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}57constexpr static thread_local double V12 = 38; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}58constexpr extern thread_local char V13; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}59// both-error@-1 {{cannot combine with previous 'extern' declaration specifier}}60// both-error@-2 {{constexpr variable declaration must be a definition}}61constexpr thread_local short V14 = 38; // both-error {{cannot combine with previous '_Thread_local' declaration specifier}}62 63// Check how constexpr works with qualifiers.64constexpr _Atomic int V15 = 0; // both-error {{constexpr variable cannot have type 'const _Atomic(int)'}}65constexpr _Atomic(int) V16 = 0; // both-error {{constexpr variable cannot have type 'const _Atomic(int)'}}66 67constexpr volatile int V17 = 0; // both-error {{constexpr variable cannot have type 'const volatile int'}}68 69constexpr int * restrict V18 = 0; // both-error {{constexpr variable cannot have type 'int *const restrict'}}70 71constexpr extern char Oops = 1; // both-error {{cannot combine with previous 'extern' declaration specifier}} \72                                // both-warning {{'extern' variable has an initializer}}73 74constexpr int * restrict * Oops1 = 0;75 76typedef _Atomic(int) TheA;77typedef volatile short TheV;78typedef float * restrict TheR;79 80constexpr TheA V19[3] = {};81// both-error@-1 {{constexpr variable cannot have type 'const TheA[3]' (aka 'const _Atomic(int)[3]')}}82constexpr TheV V20[3] = {};83// both-error@-1 {{constexpr variable cannot have type 'const TheV[3]' (aka 'const volatile short[3]')}}84constexpr TheR V21[3] = {};85// both-error@-1 {{constexpr variable cannot have type 'const TheR[3]' (aka 'float *restrict const[3]')}}86 87struct HasA {88  TheA f;89  int b;90};91 92struct HasV {93  float b;94  TheV f;95};96 97struct HasR {98  short b;99  int a;100  TheR f;101};102 103constexpr struct HasA V22[2] = {};104// both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}105constexpr struct HasV V23[2] = {};106// both-error@-1 {{constexpr variable cannot have type 'TheV' (aka 'volatile short')}}107constexpr struct HasR V24[2] = {};108// both-error@-1 {{constexpr variable cannot have type 'TheR' (aka 'float *restrict')}}109 110union U3 {111  float a;112  union {113    struct HasA f;114    struct HasR f1;115  };116};117 118constexpr union U3 V25 = {};119// both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}120constexpr union U3 V26[8] = {};121// both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}122 123struct S4 {124  union U3 f[3];125};126 127constexpr struct S4 V27 = {};128// both-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}129constexpr const int V28 = 28;130 131struct S {132  union {133    volatile int i;134  };135  int j;136};137 138constexpr struct S s = {}; // both-error {{constexpr variable cannot have type 'volatile int'}}139 140// Check that constexpr variable must have a valid initializer which is a141// constant expression.142constexpr int V29;143// both-error@-1 {{constexpr variable 'V29' must be initialized by a constant expression}}144 145struct S5 {146  int f;147};148 149constexpr struct S5 V30;150// both-error@-1 {{constexpr variable 'V30' must be initialized by a constant expression}}151constexpr struct S5 V31 = {};152 153int randomFoo() { return 7; }154 155constexpr float V32 = randomFoo();156// both-error@-1 {{constexpr variable 'V32' must be initialized by a constant expression}}157 158const int V33 = 4;159const int V34 = 0;160const int V35 = 2;161 162constexpr int V36 = V33 / V34;163// both-error@-1 {{constexpr variable 'V36' must be initialized by a constant expression}}164constexpr int V37 = V33 / V35;165// both-error@-1 {{constexpr variable 'V37' must be initialized by a constant expression}}166constexpr int V38 = 3;167constexpr int V39 = V38 / V38;168constexpr int V40 = V38 / 2;169constexpr int V41 = V38 / 0;170// both-error@-1 {{constexpr variable 'V41' must be initialized by a constant expression}}171// both-note@-2 {{division by zero}}172constexpr int V42 = V38 & 0;173 174constexpr struct S5 V43 = { randomFoo() };175// both-error@-1 {{constexpr variable 'V43' must be initialized by a constant expression}}176constexpr struct S5 V44 = { 0 };177constexpr struct S5 V45 = { V38 / 0 };178// both-error@-1 {{constexpr variable 'V45' must be initialized by a constant expression}}179// both-note@-2 {{division by zero}}180 181constexpr float V46[3] = {randomFoo() };182// both-error@-1 {{constexpr variable 'V46' must be initialized by a constant expression}}183constexpr struct S5 V47[3] = {randomFoo() };184// both-error@-1 {{constexpr variable 'V47' must be initialized by a constant expression}}185 186const static int V48 = V38;187constexpr static int V49 = V48;188// both-error@-1 {{constexpr variable 'V49' must be initialized by a constant expression}}189 190void f4(const int P1) {191  constexpr int V = P1;192// both-error@-1 {{constexpr variable 'V' must be initialized by a constant expression}}193 194  constexpr int V1 = 12;195  constexpr const int *V2 = &V1;196// both-error@-1 {{constexpr variable 'V2' must be initialized by a constant expression}}197}198 199// Check that initializer for constexpr variable should match the type of the200// variable and is exactly representable int the variable's type.201 202struct S6 {203  unsigned char a;204};205 206struct S7 {207  union {208    float a;209  };210  unsigned int b;211};212 213struct S8 {214  unsigned char a[3];215  unsigned int b[3];216};217 218constexpr struct S8 DesigInit = {.b = {299, 7, 8}, .a = {-1, 7, 8}};219// both-error@-1 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'unsigned char'}}220 221void f5() {222  constexpr char V50 = 300;223  // both-error@-1 {{constexpr initializer evaluates to 300 which is not exactly representable in type 'const char'}}224  constexpr float V51 = 1.0 / 3.0;225  // both-error@-1 {{constexpr initializer evaluates to 3.333333e-01 which is not exactly representable in type 'const float'}}226  constexpr float V52 = 0.7;227  // both-error@-1 {{constexpr initializer evaluates to 7.000000e-01 which is not exactly representable in type 'const float'}}228  constexpr float V53 = 1.0f / 3.0f;229  constexpr float V54 = 432000000000;230  // both-error@-1 {{constexpr initializer evaluates to 432000000000 which is not exactly representable in type 'const float'}}231  constexpr unsigned char V55[] = {232      "\xAF",233  // both-error@-1 {{constexpr initializer evaluates to -81 which is not exactly representable in type 'const unsigned char'}}234  };235 236  constexpr unsigned char V56[] = {237      u8"\xAF",238  };239  constexpr struct S6 V57 = {299};240  // both-error@-1 {{constexpr initializer evaluates to 299 which is not exactly representable in type 'unsigned char'}}241  constexpr struct S6 V58 = {-299};242  // both-error@-1 {{constexpr initializer evaluates to -299 which is not exactly representable in type 'unsigned char'}}243  constexpr double V59 = 0.5;244  constexpr double V60 = 1.0;245  constexpr float V61 = V59 / V60;246  constexpr double V62 = 1.7;247  constexpr float V63 = V59 / V62;248  // both-error@-1 {{constexpr initializer evaluates to 2.941176e-01 which is not exactly representable in type 'const float'}}249 250  constexpr unsigned char V64 = '\xAF';251  // both-error@-1 {{constexpr initializer evaluates to -81 which is not exactly representable in type 'const unsigned char'}}252  constexpr unsigned char V65 = u8'\xAF';253 254  constexpr char V66[3] = {300};255  // both-error@-1 {{constexpr initializer evaluates to 300 which is not exactly representable in type 'const char'}}256  constexpr struct S6 V67[3] = {300};257  // both-error@-1 {{constexpr initializer evaluates to 300 which is not exactly representable in type 'unsigned char'}}258 259  constexpr struct S7 V68 = {0.3, -1 };260  // both-error@-1 {{constexpr initializer evaluates to 3.000000e-01 which is not exactly representable in type 'float'}}261  // both-error@-2 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'unsigned int'}}262  constexpr struct S7 V69 = {0.5, -1 };263  // both-error@-1 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'unsigned int'}}264  constexpr struct S7 V70[3] = {{123456789}};265  // both-error@-1 {{constexpr initializer evaluates to 123456789 which is not exactly representable in type 'float'}}266 267  constexpr int V71 = 0.3;268  // both-error@-1 {{constexpr initializer for type 'const int' is of type 'double'}}269  constexpr int V72 = V59;270  // both-error@-1 {{constexpr initializer for type 'const int' is of type 'const double'}}271  constexpr struct S6 V73 = {V59};272  // both-error@-1 {{constexpr initializer for type 'unsigned char' is of type 'const double'}}273 274  constexpr float V74 = 1;275  constexpr float V75 = V59;276  constexpr unsigned int V76[3] = {0.5};277  // both-error@-1 {{constexpr initializer for type 'const unsigned int' is of type 'double'}}278 279  constexpr _Complex float V77 = 0;280  constexpr float V78 = V77;281  // both-error@-1 {{constexpr initializer for type 'const float' is of type 'const _Complex float'}}282  constexpr int V79 = V77;283  // both-error@-1 {{constexpr initializer for type 'const int' is of type 'const _Complex float'}}284 285}286 287constexpr char string[] = "test""ing this out\xFF";288constexpr unsigned char ustring[] = "test""ing this out\xFF";289// both-error@-1 {{constexpr initializer evaluates to -1 which is not exactly representable in type 'const unsigned char'}}290constexpr char u8string[] = u8"test"u8"ing this out\xFF";291// both-error@-1 {{constexpr initializer evaluates to 255 which is not exactly representable in type 'const char'}}292constexpr unsigned char u8ustring[] = u8"test"u8"ing this out\xFF";293constexpr unsigned short uustring[] = u"test"u"ing this out\xFF";294constexpr unsigned int Ustring[] = U"test"U"ing this out\xFF";295constexpr unsigned char Arr2[6][6] = {296  {"ek\xFF"}, {"ek\xFF"}297// both-error@-1 2{{constexpr initializer evaluates to -1 which is not exactly representable in type 'const unsigned char'}}298};299 300constexpr int i = (12);301constexpr int j = (i);302constexpr unsigned jneg = (-i);303// both-error@-1 {{constexpr initializer evaluates to -12 which is not exactly representable in type 'const unsigned int'}}304 305// Check that initializer for pointer constexpr variable should be null.306constexpr int V80 = 3;307constexpr const int *V81 = &V80;308// both-error@-1 {{constexpr pointer initializer is not null}}309constexpr int *V82 = 0;310constexpr int *V83 = V82;311constexpr int *V84 = 42;312// both-error@-1 {{constexpr variable 'V84' must be initialized by a constant expression}}313// both-note@-2 {{this conversion is not allowed in a constant expression}}314// both-error@-3 {{constexpr pointer initializer is not null}}315constexpr int *V85 = nullptr;316 317// Check that constexpr variables should not be VLAs.318void f6(const int P1) {319  constexpr int V86[P1] = {};320// both-error@-1 {{constexpr variable cannot have type 'const int[P1]'}}321  const int V87 = 3;322  constexpr int V88[V87] = {};323// both-warning@-1 {{variable length array folded to constant array as an extension}}324  int V89 = 7;325  constexpr int V90[V89] = {};326// both-error@-1 {{constexpr variable cannot have type 'const int[V89]'}}327}328 329void f7(int n, int array[n]) {330  constexpr typeof(array) foo = 0; // Accepted because array is a pointer type, not a VLA type331  int (*(*fp)(int n))[n];332  constexpr typeof(fp) bar = 0; // both-error {{constexpr variable cannot have type 'const typeof (fp)' (aka 'int (*(*const)(int))[n]')}}333}334 335// Check how constexpr works with NaNs and infinities.336#define FLT_NAN __builtin_nanf("1")337#define DBL_NAN __builtin_nan("1")338#define LD_NAN __builtin_nanf("1")339#define FLT_SNAN __builtin_nansf("1")340#define DBL_SNAN __builtin_nans("1")341#define LD_SNAN __builtin_nansl("1")342#define INF __builtin_inf()343void infsNaNs() {344  // Inf and quiet NaN is always fine, signaling NaN must have the same type.345  constexpr float fl0 = INF;346  constexpr float fl1 = (long double)INF;347  constexpr float fl2 = (long double)FLT_NAN;348  constexpr float fl3 = FLT_NAN;349  constexpr float fl5 = DBL_NAN;350  constexpr float fl6 = LD_NAN;351  constexpr float fl7 = DBL_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const float'}}352  constexpr float fl8 = LD_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const float'}}353 354  constexpr double db0 = FLT_NAN;355  constexpr double db2 = DBL_NAN;356  constexpr double db3 = DBL_SNAN;357  constexpr double db4 = FLT_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const double'}}358  constexpr double db5 = LD_SNAN; // both-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const double'}}359  constexpr double db6 = INF;360}361 362constexpr struct S9 s9 = {  }; // both-error {{variable has incomplete type 'const struct S9'}} \363                               // both-note {{forward declaration of 'struct S9'}}364 365struct S10 {366  signed long long i : 8;367};368constexpr struct S10 c = { 255 };369// FIXME-expected-error@-1 {{constexpr initializer evaluates to 255 which is not exactly representable in 'long long' bit-field with width 8}}370// See: GH#101299371