1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2 // RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s
3 // RUN: %clang_cc1 -verify=ref,both %s
4 // RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
12 static_assert(a
.a
== 12, "");
13 static_assert(a
.b
== 0, ""); // both-error {{not an integral constant expression}} \
14 // both-note {{read of member 'b' of union with active member 'a'}}
20 static_assert(u1
.f
== 3.0, "");
21 static_assert(u1
.i
== 1, ""); // both-error {{not an integral constant expression}} \
22 // both-note {{read of member 'i' of union with active member 'f'}}
30 constexpr A aa
= {1, 2.0}; // both-error {{excess elements in union initializer}}
31 constexpr A ab
= {.d
= 1.0};
32 static_assert(ab
.d
== 1.0, "");
33 static_assert(ab
.a
== 1, ""); // both-error {{not an integral constant expression}} \
34 // both-note {{read of member 'a' of union with active member 'd'}}
42 namespace SimpleStore
{
52 static_assert(foo() == 10, "");
54 constexpr int empty() {
55 A a
{}; /// Just test that this works.
58 static_assert(empty() == 10, "");
68 static_assert(z
.f
== 0.0, "");
71 namespace DefaultInit
{
77 constexpr U1 u1
; /// OK.
81 return u
.a
; // both-note {{read of member 'a' of union with active member 'b'}}
83 static_assert(foo() == 42); // both-error {{not an integral constant expression}} \
84 // both-note {{in call to}}
87 #if __cplusplus >= 202002L
88 namespace SimpleActivate
{
89 constexpr int foo() { // both-error {{never produces a constant expression}}
97 return Z
.a
; // both-note 2{{read of member 'a' of union with active member 'b'}}
99 static_assert(foo() == 20); // both-error {{not an integral constant expression}} \
100 // both-note {{in call to}}
102 constexpr int foo2() {
112 static_assert(foo2() == 20);
115 constexpr int foo3() {
125 return Z
.a
.x
; // both-note {{read of uninitialized object}}
127 static_assert(foo3() == 10); // both-error {{not an integral constant expression}} \
128 // both-note {{in call to}}
130 constexpr int foo4() {
143 static_assert(foo4() == 100);
146 namespace IndirectFieldDecl
{
148 union { int a
, b
= 2, c
; };
149 union { int d
, e
= 5, f
; };
150 constexpr C() : a(1) {}
152 static_assert(C().a
== 1, "");
155 namespace UnionDtor
{
159 constexpr U(int *I
) : I(I
) {}
165 constexpr int foo() {
172 static_assert(foo() == 10);
175 namespace UnionMemberDtor
{
179 constexpr UM(int &I
) : I(I
) {}
180 constexpr ~UM() { I
= 200; }
185 constexpr U(int &I
) : um(I
) {}
190 constexpr int foo() {
198 static_assert(foo() == 100);
214 constexpr int foo() { // both-error {{constexpr function never produces a constant expression}}
217 int a
= u
.y
; // both-note 2{{read of member 'y' of union with active member 'u' is not allowed in a constant expression}}
221 static_assert(foo() == 1); // both-error {{not an integral constant expression}} \
222 // both-note {{in call to}}
224 constexpr int foo2() {
229 static_assert(foo2() == 10);
231 constexpr int foo3() { // both-error {{constexpr function never produces a constant expression}}
234 int a
= u
.u
.b
; // both-note 2{{read of member 'b' of union with active member 'a' is not allowed in a constant expression}}
238 static_assert(foo3() == 1); // both-error {{not an integral constant expression}} \
239 // both-note {{in call to}}
241 constexpr int foo4() { // both-error {{constexpr function never produces a constant expression}}
246 return u
.u
.a
; // both-note 2{{read of member 'u' of union with active member 'x' is not allowed in a constant expression}}
248 static_assert(foo4() == 1); // both-error {{not an integral constant expression}} \
249 // both-note {{in call to}}
255 struct non_trivial_constructor
{
256 constexpr non_trivial_constructor() : x(100) {}
261 non_trivial_constructor b
;
264 static_assert(U2().b
.x
== 100, ""); // both-error {{not an integral constant expression}} \
265 // both-note {{read of member 'b' of union with active member 'a'}}
267 union { int a
; int b
; } constexpr u1
{};
268 static_assert(u1
.a
== 0, "");
269 static_assert(u1
.b
== 0, ""); // both-error {{not an integral constant expression}} \
270 // both-note {{read of member 'b' of union with active member 'a'}}
272 union U
{ int a
; int b
; } constexpr u2
= U();
273 static_assert(u2
.a
== 0, "");
274 static_assert(u2
.b
== 0, ""); // both-error {{not an integral constant expression}} \
275 // both-note {{read of member 'b' of union with active member 'a'}}
278 struct F
{int x
; int y
; };
279 union { F a
; int b
; } constexpr u3
{};
280 static_assert(u3
.a
.x
== 0, "");
282 union U4
{ F a
; int b
; } constexpr u4
= U4();
283 static_assert(u4
.a
.x
== 0, "");
285 union { int a
[5]; int b
; } constexpr u5
{};
286 static_assert(u5
.a
[0] == 0, "");
287 static_assert(u5
.a
[4] == 0, "");
288 static_assert(u5
.b
== 0, ""); // both-error {{not an integral constant expression}} \
289 // both-note {{read of member 'b' of union with active member 'a'}}
291 union U6
{ int a
[5]; int b
; } constexpr u6
= U6();
292 static_assert(u6
.a
[0] == 0, "");
293 static_assert(u6
.a
[4] == 0, "");
294 static_assert(u6
.b
== 0, ""); // both-error {{not an integral constant expression}} \
295 // both-note {{read of member 'b' of union with active member 'a'}}
297 union UnionWithUnnamedBitfield
{
301 static_assert(UnionWithUnnamedBitfield().n
== 0, "");
302 static_assert(UnionWithUnnamedBitfield
{}.n
== 0, "");
303 static_assert(UnionWithUnnamedBitfield
{1}.n
== 1, "");
306 namespace IndirectField
{
322 constexpr S(int a
, int b
, int d
, int e
) : a(a
), b(b
), d(d
), e(e
) {}
323 constexpr S(int c
, int d
, int f
) : c(c
), d(d
), f(f
) {}
326 constexpr S
s1(1,2,3,4);
327 constexpr S
s2(5, 6, 7);
329 static_assert(s1
.a
== 1, "");
330 static_assert(s1
.b
== 2, "");
332 static_assert(s1
.c
== 0, ""); // both-error {{constant expression}} both-note {{union with active member}}
333 static_assert(s1
.d
== 3, "");
334 static_assert(s1
.e
== 4, "");
335 static_assert(s1
.f
== 0, ""); // both-error {{constant expression}} both-note {{union with active member}}
337 static_assert(s2
.a
== 0, ""); // both-error {{constant expression}} both-note {{union with active member}}
338 static_assert(s2
.b
== 0, ""); // both-error {{constant expression}} both-note {{union with active member}}
339 static_assert(s2
.c
== 5, "");
340 static_assert(s2
.d
== 6, "");
341 static_assert(s2
.e
== 0, ""); // both-error {{constant expression}} both-note {{union with active member}}
342 static_assert(s2
.f
== 7, "");
351 constexpr U x
= {42};
353 static_assert(y
.a
== 42, "");
354 static_assert(y
.b
== 42, ""); // both-error {{constant expression}} \
355 // both-note {{'b' of union with active member 'a'}}
358 namespace UnionInBase
{
360 int y
; // both-note {{subobject declared here}}
371 constexpr int read_wrong_member_indirect() { // both-error {{never produces a constant}}
374 return *p
; // both-note 2{{read of member 'a' of union with active member 'b'}}
377 static_assert(read_wrong_member_indirect() == 1); // both-error {{not an integral constant expression}} \
378 // both-note {{in call to}}
379 constexpr int read_uninitialized() {
383 return *p
; // both-note {{read of uninitialized object}}
385 static_assert(read_uninitialized() == 0); // both-error {{constant}} \
386 // both-note {{in call}}
387 constexpr int write_uninitialized() {
395 constexpr B
return_uninit() {
400 constexpr B uninit
= return_uninit(); // both-error {{constant expression}} \
401 // both-note {{subobject 'y' is not initialized}}
402 static_assert(return_uninit().a
.x
== 2);