c: Update checks on constexpr floating-point initializers
[platform/upstream/gcc.git] / gcc / testsuite / gcc.dg / c2x-constexpr-3.c
1 /* Test C2x constexpr.  Invalid code.  */
2 /* { dg-do compile } */
3 /* { dg-options "-std=c2x -pedantic-errors" } */
4
5 extern constexpr int v0 = 0; /* { dg-error "'constexpr' used with 'extern'" } */
6 /* { dg-warning "initialized and declared 'extern'" "initialized extern" { target *-*-* } .-1 } */
7 constexpr extern int v1 = 0; /* { dg-error "'constexpr' used with 'extern'" } */
8 /* { dg-warning "initialized and declared 'extern'" "initialized extern" { target *-*-* } .-1 } */
9 typedef constexpr int v2; /* { dg-error "'constexpr' used with 'typedef'" } */
10 constexpr typedef int v3; /* { dg-error "'constexpr' used with 'typedef'" } */
11 thread_local constexpr int v4 = 0; /* { dg-error "'constexpr' used with '_Thread_local'" } */
12 constexpr thread_local int v5 = 0; /* { dg-error "'thread_local' used with 'constexpr'" } */
13 constexpr constexpr int v6 = 1; /* { dg-error "duplicate 'constexpr'" } */
14 constexpr struct v7; /* { dg-error "'constexpr' in empty declaration" } */
15 /* { dg-error "'struct v7' declared in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
16 constexpr union v8; /* { dg-error "'constexpr' in empty declaration" } */
17 /* { dg-error "'union v8' declared in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
18 constexpr struct v9 { int a; }; /* { dg-error "'constexpr' in empty declaration" } */
19 /* { dg-error "'struct v9' defined in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
20 constexpr union v10 { int a; }; /* { dg-error "'constexpr' in empty declaration" } */
21 /* { dg-error "'union v10' defined in underspecified object declaration" "underspecified" { target *-*-* } .-1 } */
22 constexpr; /* { dg-error "'constexpr' in empty declaration" } */
23 constexpr int; /* { dg-error "empty declaration" } */
24 constexpr const; /* { dg-error "empty declaration" } */
25 constexpr int v11; /* { dg-error "initialized data declaration" } */
26 constexpr int v12 { } /* { dg-error "initialized data declaration" } */
27 constexpr int v13 = 1, v14 = 2; /* { dg-error "single declarator" } */
28 constexpr int v15 = sizeof (struct v16 *); /* { dg-error "declared in underspecified object initializer" } */
29 constexpr int v17 = sizeof (union v18 *); /* { dg-error "declared in underspecified object initializer" } */
30 constexpr int v19 = sizeof (struct v20 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
31 constexpr int v21 = sizeof (struct { int a; }); /* { dg-error "defined in underspecified object initializer" } */
32 constexpr int v22 = sizeof (union v23 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
33 constexpr int v24 = sizeof (union { int a; }); /* { dg-error "defined in underspecified object initializer" } */
34 constexpr int v25 = sizeof (enum v26 { A }); /* { dg-error "defined in underspecified object initializer" } */
35 /* The following case is undefined behavior (so doesn't actually require a
36    diagnostic).  */
37 constexpr int v27 = sizeof (enum { B }); /* { dg-error "defined in underspecified object initializer" } */
38 /* Examples with a forward declaration, then definition inside constexpr.  */
39 struct v28;
40 constexpr int v29 = sizeof (struct v28 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
41 union v30;
42 constexpr int v31 = sizeof (union v30 { int a; }); /* { dg-error "defined in underspecified object initializer" } */
43 constexpr int v32 = sizeof (v32); /* { dg-error "underspecified 'v32' referenced in its initializer" } */
44 static const int v33;
45 constexpr const int v33 = 1; /* { dg-error "underspecified declaration of 'v33', which is already declared in this scope" } */
46 constexpr void v34 () {} /* { dg-error "'constexpr' requires an initialized data declaration" } */
47 void v35 (constexpr int v36); /* { dg-error "storage class specified for parameter 'v36'" } */
48 void v37 (constexpr short); /* { dg-error "storage class specified for unnamed parameter" } */
49 void v38 (constexpr register int v39); /* { dg-error "storage class specified for parameter 'v39'" } */
50 void v40 (constexpr register short); /* { dg-error "storage class specified for unnamed parameter" } */
51 /* The following case is undefined behavior (presumably to allow for possible
52    future support for constexpr functions), but should clearly be diagnosed
53    when such functions aren't actually supported.  */
54 constexpr int v41 (); /* { dg-error "'constexpr' requires an initialized data declaration" } */
55 typedef volatile long t42;
56 typedef int *restrict t43;
57 typedef _Atomic int t44;
58 struct t45 { struct { struct { t42 a[2]; } a; } a; };
59 struct t46 { struct { struct { int z; int *restrict a; } a[3]; } a; };
60 struct t47 { short x; struct { struct { _Atomic long a; } a; } a[4][5]; };
61 constexpr t42 v48 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
62 constexpr t43 v49 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
63 constexpr t44 v50 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
64 constexpr volatile double v51 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
65 constexpr int *restrict v52 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
66 constexpr _Atomic (short) v53 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
67 constexpr long *volatile v54 = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
68 constexpr struct t45 v55 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
69 constexpr struct t46 v56 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
70 constexpr struct t47 v57 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
71 union t58 { struct { union { t42 a[1]; } a; } a; };
72 union t59 { struct { union { int z; int *restrict a; } a; } a; };
73 union t60 { short x; union { struct { _Atomic long a; } a[3]; } a; };
74 constexpr union t58 v61 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
75 constexpr union t59 v62 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
76 constexpr union t60 v63 = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
77 constexpr t42 v64[1][2][3] = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
78 constexpr volatile int v65[1][2][3] = {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
79 constexpr struct t45 v66[2][2][4] = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
80 constexpr union t60 v67[2][2][4] = {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
81 int v68 = 0;
82 constexpr int v69 = v68; /* { dg-error "initializer element is not constant" } */
83 double exp (double);
84 constexpr double v70 = exp (0); /* { dg-error "initializer element is not a constant expression" } */
85 struct s71 { int a; double b; };
86 constexpr struct s71 v72 = { 0, exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
87 /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
88 constexpr struct s71 v73 = { v68, 0 }; /* { dg-error "initializer element is not constant" } */
89 union u74 { int a; double b; };
90 constexpr union u74 v75 = { v68 }; /* { dg-error "initializer element is not constant" } */
91 constexpr union u74 v76 = { .b = exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
92 /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
93 constexpr struct s77 *v77 = 0; /* { dg-error "'struct s77' declared in underspecified object declaration" } */
94 constexpr union u78 *v78 = 0; /* { dg-error "'union u78' declared in underspecified object declaration" } */
95 constexpr struct s79 { int a; } v79 = { 0 }; /* { dg-error "'struct s79' defined in underspecified object declaration" } */
96 constexpr union u80 { int a; } v80 = { 0 }; /* { dg-error "'union u80' defined in underspecified object declaration" } */
97 constexpr enum e81 { E81 } v81 = E81; /* { dg-error "'enum e81' defined in underspecified object declaration" } */
98 constexpr enum { E82 } v82 = E82; /* { dg-error "defined in underspecified object declaration" } */
99 struct s83 constexpr *v83 = 0; /* { dg-error "'struct s83' declared in underspecified object declaration" } */
100 union u84 constexpr *v84 = 0; /* { dg-error "'union u84' declared in underspecified object declaration" } */
101 struct s85 { int a; } constexpr v85 = { 0 }; /* { dg-error "'struct s85' defined in underspecified object declaration" } */
102 union u86 { int a; } constexpr v86 = { 0 }; /* { dg-error "'union u86' defined in underspecified object declaration" } */
103 enum e87 { E87 } constexpr v87 = E87; /* { dg-error "'enum e87' defined in underspecified object declaration" } */
104 enum { E88 } constexpr v88 = E88; /* { dg-error "defined in underspecified object declaration" } */
105 constexpr int *v89 = (int *) 0; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
106 constexpr void *v90 = (void *) (void *) 0; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
107 constexpr int v91 = (int) (double) 1.0; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
108 constexpr struct s71 v92 = { (int) (double) 1.0, 0 }; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
109 struct s93 { void *p; };
110 constexpr struct s93 v94 = { (int *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
111 constexpr int v95 = (unsigned int) -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
112 constexpr unsigned char v96 = -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
113 constexpr signed char v97 = 1234567LL; /* { dg-error "'constexpr' initializer not representable in type of object" } */
114 /* { dg-warning "overflow in conversion" "overflow warning" { target *-*-* } .-1 } */
115 constexpr double v98 = __builtin_complex (1.0, 0.0); /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
116 constexpr double v99 = __builtin_complex (1.0, 1.0); /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
117 constexpr double v100 = __builtin_complex (1.0, -0.0); /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
118 constexpr float v102 = (unsigned long long) -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
119 constexpr double v103 = (unsigned long long) -1; /* { dg-error "'constexpr' initializer not representable in type of object" } */
120 constexpr float v104 = __LONG_LONG_MAX__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
121 constexpr double v105 = __LONG_LONG_MAX__; /* { dg-error "'constexpr' initializer not representable in type of object" } */
122 constexpr signed char v106[] = u8"\xff"; /* { dg-error "'constexpr' initializer not representable in type of object" } */
123 /* Only the initialized (possibly by default) element of a constexpr union is a
124    named constant.  */
125 union u107 { int a; int b; };
126 constexpr union u107 v108 = { };
127 constexpr union u107 v109 = { .a = 0 };
128 constexpr union u107 v110 = { .b = 0 };
129 constexpr int v111 = v108.b; /* { dg-error "initializer" } */
130 constexpr int v112 = v109.b; /* { dg-error "initializer" } */
131 constexpr int v113 = v110.a; /* { dg-error "initializer" } */
132 /* A reference to an array in a constexpr object is converted to a pointer as
133    usual, so in particular is not equivalent to directly using a string literal
134    initializer extracted from the initializer of that object.  */
135 struct s114 { char c[10]; };
136 constexpr struct s114 v115 = { "abc" };
137 constexpr struct s114 v116 = { v115.c }; /* { dg-error "initializer" } */
138 /* { dg-error "integer from pointer" "conversion" { target *-*-* } .-1 } */
139
140 void
141 f0 ()
142 {
143   (constexpr constexpr int) { 1 }; /* { dg-error "duplicate 'constexpr'" } */
144   (constexpr thread_local int) { 1 }; /* { dg-error "'thread_local' used with 'constexpr'" } */
145   (thread_local constexpr static int) { 1 }; /* { dg-error "'constexpr' used with '_Thread_local'" } */
146   (constexpr int) { sizeof (struct fs1 *) }; /* { dg-error "declared in underspecified object initializer" } */
147   (constexpr int) { sizeof (union fs2 *) }; /* { dg-error "declared in underspecified object initializer" } */
148   (constexpr int) { sizeof (struct fs3 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
149   (constexpr int) { sizeof (struct { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
150   (constexpr int) { sizeof (union fs4 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
151   (constexpr int) { sizeof (union { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
152   (constexpr int) { sizeof (enum fs5 { A }) }; /* { dg-error "defined in underspecified object initializer" } */
153   /* The following case is undefined behavior (so doesn't actually require a
154      diagnostic).  */
155   (constexpr int) { sizeof (enum { B }) }; /* { dg-error "defined in underspecified object initializer" } */
156   /* Examples with a forward declaration, then definition inside constexpr.  */
157   struct fs6;
158   (constexpr int) { sizeof (struct fs6 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
159   union fs7;
160   (constexpr int) { sizeof (union fs7 { int a; }) }; /* { dg-error "defined in underspecified object initializer" } */
161   constexpr int fv32 = sizeof (fv32); /* { dg-error "underspecified 'fv32' referenced in its initializer" } */
162   /* Test entering then exiting nested underspecified initializers.  */
163   constexpr int x = (constexpr int) { 1 } + sizeof (struct fs8 *); /* { dg-error "declared in underspecified object initializer" } */
164   auto y = (constexpr int) { 1 } + sizeof (struct fs9 *); /* { dg-error "declared in underspecified object initializer" } */
165   extern const int z; /* { dg-message "previous declaration" } */
166   constexpr const int z = 1; /* { dg-error "underspecified declaration of 'z', which is already declared in this scope" } */
167   /* { dg-error "declaration of 'z' with no linkage follows extern declaration" "linkage error" { target *-*-* } .-1 } */
168   int non_const = 1;
169   typedef int VLA[non_const];
170   constexpr VLA *pnc = nullptr; /* { dg-error "'constexpr' object has variably modified type" } */
171   (constexpr t42) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
172   (constexpr t43) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
173   (constexpr t44) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
174   (constexpr volatile double) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
175   (constexpr int *restrict) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
176   (constexpr _Atomic (short)) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
177   (constexpr long *volatile) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
178   (constexpr struct t45) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
179   (constexpr struct t46) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
180   (constexpr struct t47) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
181   (constexpr union t58) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
182   (constexpr union t59) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
183   (constexpr union t60) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
184   (constexpr t42 [1][2][3]) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
185   (constexpr volatile int [1][2][3]) {}; /* { dg-error "invalid qualifiers for 'constexpr' object" } */
186   (constexpr struct t45 [2][2][4]) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
187   (constexpr union t60 [2][2][4]) {}; /* { dg-error "invalid qualifiers for field of 'constexpr' object" } */
188   (constexpr int) { v68 }; /* { dg-error "initializer element is not constant" } */
189   (constexpr double) { exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
190   /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
191   (constexpr struct s71) { 0, exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
192   /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
193   (constexpr struct s71) { v68, 0 }; /* { dg-error "initializer element is not constant" } */
194   (constexpr union u74) { v68 }; /* { dg-error "initializer element is not constant" } */
195   (constexpr union u74) { .b = exp (0) }; /* { dg-error "initializer element is not a constant expression" } */
196   /* { dg-error "'constexpr' initializer is not an arithmetic constant expression" "arithmetic" { target *-*-* } .-1 } */
197   (constexpr struct fs10 *) { 0 }; /* { dg-error "declared in 'constexpr' compound literal" } */
198   (constexpr union fs11 *) { 0 }; /* { dg-error "declared in 'constexpr' compound literal" } */
199   (constexpr struct fs12 { int a; }) { 0 }; /* { dg-error "defined in 'constexpr' compound literal" } */
200   (constexpr union fs13 { int a; }) { 0 }; /* { dg-error "defined in 'constexpr' compound literal" } */
201   (constexpr enum fs14 { FS14 }) { FS14 }; /* { dg-error "defined in 'constexpr' compound literal" } */
202   (constexpr enum { FS15 }) { FS15 }; /* { dg-error "defined in 'constexpr' compound literal" } */
203   (constexpr int *) { (int *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
204   (constexpr void *) { (void *) (void *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
205   (constexpr int) { (int) (double) 1.0 }; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
206   (constexpr struct s71) { (int) (double) 1.0, 0 }; /* { dg-error "constexpr' integer initializer is not an integer constant expression" } */
207   (constexpr struct s93) { (int *) 0 }; /* { dg-error "'constexpr' pointer initializer is not a null pointer constant" } */
208   (constexpr int) { (unsigned int) -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
209   (constexpr unsigned char) { -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
210   (constexpr signed char) { 1234567LL }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
211   /* { dg-warning "overflow in conversion" "overflow warning" { target *-*-* } .-1 } */
212   (constexpr double) { __builtin_complex (1.0, 0.0) }; /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
213   (constexpr double) { __builtin_complex (1.0, 1.0) }; /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
214   (constexpr double) { __builtin_complex (1.0, -0.0) }; /* { dg-error "'constexpr' initializer for a real type is of complex type" } */
215   (constexpr float) { (unsigned long long) -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
216   (constexpr double) { (unsigned long long) -1 }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
217   (constexpr float) { __LONG_LONG_MAX__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
218   (constexpr double) { __LONG_LONG_MAX__ }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
219   (constexpr signed char []) { u8"\xff" }; /* { dg-error "'constexpr' initializer not representable in type of object" } */
220   constexpr typeof (nullptr) not_npc = nullptr;
221   int *ptr = 0;
222   (void) (ptr == not_npc); /* { dg-error "invalid operands" } */
223   /* auto may only be used with another storage class specifier, such as
224      constexpr, if the type is inferred.  */
225   auto constexpr int a_c_t = 1; /* { dg-error "'auto' used with 'constexpr'" } */
226   constexpr auto int c_a_t = 1; /* { dg-error "'auto' used with 'constexpr'" } */
227   auto int constexpr a_t_c = 1; /* { dg-error "'constexpr' used with 'auto'" } */
228   constexpr int auto c_t_a = 1; /* { dg-error "'auto' used with 'constexpr'" } */
229   int auto constexpr t_a_c = 1; /* { dg-error "'constexpr' used with 'auto'" } */
230   int constexpr auto t_c_a = 1; /* { dg-error "'auto' used with 'constexpr'" } */
231 }