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