1 // RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -Wno-div-by-zero %s
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}}
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}}
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}}
17 // expected-error@-1 {{type name does not allow constexpr}}
18 // expected-error@-2 {{expected ';' at end}}
21 constexpr; // expected-error {{'constexpr' can only be used in variable declarations}}
23 constexpr float V2
= 7.0;
24 int V3
= (constexpr)3; // expected-error {{expected expression}}
28 constexpr float b
= 1.7f
;
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));
47 typedef constexpr int Foo
; // expected-error {{typedef cannot be constexpr}}
48 constexpr typedef int Bar
; // expected-error {{typedef cannot be constexpr}}
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;
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}}
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)'}}
66 constexpr volatile int V17
= 0; // expected-error {{constexpr variable cannot have type 'const volatile int'}}
68 constexpr int * restrict V18
= 0; // expected-error {{constexpr variable cannot have type 'int *const restrict'}}
70 constexpr extern char Oops
= 1; // expected-error {{cannot combine with previous 'extern' declaration specifier}} \
71 // expected-warning {{'extern' variable has an initializer}}
73 constexpr int * restrict
* Oops1
= 0;
75 typedef _Atomic(int) TheA
;
76 typedef volatile short TheV
;
77 typedef float * restrict TheR
;
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]')}}
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')}}
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)')}}
126 constexpr struct S4 V27
= {};
127 // expected-error@-1 {{constexpr variable cannot have type 'TheA' (aka '_Atomic(int)')}}
128 constexpr const int V28
= 28;
137 constexpr struct S s
= {}; // expected-error {{constexpr variable cannot have type 'volatile int'}}
139 // Check that constexpr variable must have a valid initializer which is a
140 // constant expression.
142 // expected-error@-1 {{constexpr variable 'V29' must be initialized by a constant expression}}
148 constexpr struct S5 V30
;
149 // expected-error@-1 {{constexpr variable 'V30' must be initialized by a constant expression}}
150 constexpr struct S5 V31
= {};
152 int randomFoo() { return 7; }
154 constexpr float V32
= randomFoo();
155 // expected-error@-1 {{constexpr variable 'V32' must be initialized by a constant expression}}
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;
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}}
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}}
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}}
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}}
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}}
198 // Check that initializer for constexpr variable should match the type of the
199 // variable and is exactly representable int the variable's type.
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'}}
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
[] = {
232 // expected-error@-1 {{constexpr initializer evaluates to -81 which is not exactly representable in type 'const unsigned char'}}
235 constexpr unsigned char V56
[] = {
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'}}
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';
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'}}
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'}}
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'}}
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'}}
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'}}
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'}}
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'}}
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;
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]'}}
321 constexpr int V88
[V87
] = {};
322 // expected-warning@-1 {{variable length array folded to constant array as an extension}}
324 constexpr int V90
[V89
] = {};
325 // expected-error@-1 {{constexpr variable cannot have type 'const int[V89]'}}
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]')}}
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()
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'}}
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
;
361 constexpr struct S9 s9
= { }; // expected-error {{variable has incomplete type 'const struct S9'}} \
362 // expected-note {{forward declaration of 'struct S9'}}
365 signed long long i
: 8;
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}}
372 if constexpr (300) {} //expected-error {{expected '(' after 'if'}}
375 if consteval (300) {} //expected-error {{expected '(' after 'if'}}
381 void ghissue112516() {
383 constexpr int num
= s11
->len
; // expected-error {{constexpr variable 'num' must be initialized by a constant expression}}
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}}