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