1a07aba5dSTimm Baeder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s 2a07aba5dSTimm Baeder // RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -verify=expected,both %s 3a07aba5dSTimm Baeder // RUN: %clang_cc1 -verify=ref,both %s 4a07aba5dSTimm Baeder // RUN: %clang_cc1 -std=c++20 -verify=ref,both %s 5a07aba5dSTimm Baeder 6a07aba5dSTimm Baeder union U { 7a07aba5dSTimm Baeder int a; 8a07aba5dSTimm Baeder int b; 9a07aba5dSTimm Baeder }; 10a07aba5dSTimm Baeder 11a07aba5dSTimm Baeder constexpr U a = {12}; 12a07aba5dSTimm Baeder static_assert(a.a == 12, ""); 13a07aba5dSTimm Baeder static_assert(a.b == 0, ""); // both-error {{not an integral constant expression}} \ 14a07aba5dSTimm Baeder // both-note {{read of member 'b' of union with active member 'a'}} 15a07aba5dSTimm Baeder union U1 { 16a07aba5dSTimm Baeder int i; 17a07aba5dSTimm Baeder float f = 3.0f; 18a07aba5dSTimm Baeder }; 19a07aba5dSTimm Baeder constexpr U1 u1{}; 20a07aba5dSTimm Baeder static_assert(u1.f == 3.0, ""); 21a07aba5dSTimm Baeder static_assert(u1.i == 1, ""); // both-error {{not an integral constant expression}} \ 22a07aba5dSTimm Baeder // both-note {{read of member 'i' of union with active member 'f'}} 23a07aba5dSTimm Baeder 24a07aba5dSTimm Baeder 25a07aba5dSTimm Baeder 26a07aba5dSTimm Baeder union A { 27a07aba5dSTimm Baeder int a; 28a07aba5dSTimm Baeder double d; 29a07aba5dSTimm Baeder }; 30a07aba5dSTimm Baeder constexpr A aa = {1, 2.0}; // both-error {{excess elements in union initializer}} 31a07aba5dSTimm Baeder constexpr A ab = {.d = 1.0}; 32a07aba5dSTimm Baeder static_assert(ab.d == 1.0, ""); 33a07aba5dSTimm Baeder static_assert(ab.a == 1, ""); // both-error {{not an integral constant expression}} \ 34a07aba5dSTimm Baeder // both-note {{read of member 'a' of union with active member 'd'}} 35a07aba5dSTimm Baeder 36a07aba5dSTimm Baeder 37a07aba5dSTimm Baeder namespace Empty { 38a07aba5dSTimm Baeder union E {}; 39a07aba5dSTimm Baeder constexpr E e{}; 40a07aba5dSTimm Baeder } 41a07aba5dSTimm Baeder 42a07aba5dSTimm Baeder namespace SimpleStore { 43a07aba5dSTimm Baeder union A { 44a07aba5dSTimm Baeder int a; 45a07aba5dSTimm Baeder int b; 46a07aba5dSTimm Baeder }; 47a07aba5dSTimm Baeder constexpr int foo() { 48a07aba5dSTimm Baeder A a{.b = 4}; 49a07aba5dSTimm Baeder a.b = 10; 50a07aba5dSTimm Baeder return a.b; 51a07aba5dSTimm Baeder } 52a07aba5dSTimm Baeder static_assert(foo() == 10, ""); 53a07aba5dSTimm Baeder 54a07aba5dSTimm Baeder constexpr int empty() { 55a07aba5dSTimm Baeder A a{}; /// Just test that this works. 56a07aba5dSTimm Baeder return 10; 57a07aba5dSTimm Baeder } 58a07aba5dSTimm Baeder static_assert(empty() == 10, ""); 59a07aba5dSTimm Baeder } 60a07aba5dSTimm Baeder 61a07aba5dSTimm Baeder namespace ZeroInit { 62a07aba5dSTimm Baeder struct S { int m; }; 63a07aba5dSTimm Baeder union Z { 64a07aba5dSTimm Baeder float f; 65a07aba5dSTimm Baeder }; 66a07aba5dSTimm Baeder 67a07aba5dSTimm Baeder constexpr Z z{}; 68a07aba5dSTimm Baeder static_assert(z.f == 0.0, ""); 69a07aba5dSTimm Baeder } 70a07aba5dSTimm Baeder 71a07aba5dSTimm Baeder namespace DefaultInit { 72a07aba5dSTimm Baeder union U1 { 73a07aba5dSTimm Baeder constexpr U1() {} 74a07aba5dSTimm Baeder int a, b = 42; 75a07aba5dSTimm Baeder }; 76a07aba5dSTimm Baeder 77a07aba5dSTimm Baeder constexpr U1 u1; /// OK. 78a07aba5dSTimm Baeder 79a07aba5dSTimm Baeder constexpr int foo() { 80a07aba5dSTimm Baeder U1 u; 81a07aba5dSTimm Baeder return u.a; // both-note {{read of member 'a' of union with active member 'b'}} 82a07aba5dSTimm Baeder } 83a07aba5dSTimm Baeder static_assert(foo() == 42); // both-error {{not an integral constant expression}} \ 84a07aba5dSTimm Baeder // both-note {{in call to}} 85a07aba5dSTimm Baeder } 86a07aba5dSTimm Baeder 87a07aba5dSTimm Baeder #if __cplusplus >= 202002L 88a07aba5dSTimm Baeder namespace SimpleActivate { 89df11ee21STimm Baeder constexpr int foo() { // both-error {{never produces a constant expression}} 90a07aba5dSTimm Baeder union { 91a07aba5dSTimm Baeder int a; 92a07aba5dSTimm Baeder int b; 93a07aba5dSTimm Baeder } Z; 94a07aba5dSTimm Baeder 95a07aba5dSTimm Baeder Z.a = 10; 96a07aba5dSTimm Baeder Z.b = 20; 97df11ee21STimm Baeder return Z.a; // both-note 2{{read of member 'a' of union with active member 'b'}} 98a07aba5dSTimm Baeder } 99a07aba5dSTimm Baeder static_assert(foo() == 20); // both-error {{not an integral constant expression}} \ 100a07aba5dSTimm Baeder // both-note {{in call to}} 101a07aba5dSTimm Baeder 102a07aba5dSTimm Baeder constexpr int foo2() { 103a07aba5dSTimm Baeder union { 104a07aba5dSTimm Baeder int a; 105a07aba5dSTimm Baeder int b; 106a07aba5dSTimm Baeder } Z; 107a07aba5dSTimm Baeder 108a07aba5dSTimm Baeder Z.a = 10; 109a07aba5dSTimm Baeder Z.b = 20; 110a07aba5dSTimm Baeder return Z.b; 111a07aba5dSTimm Baeder } 112a07aba5dSTimm Baeder static_assert(foo2() == 20); 113a07aba5dSTimm Baeder 114a07aba5dSTimm Baeder 115a07aba5dSTimm Baeder constexpr int foo3() { 116a07aba5dSTimm Baeder union { 117a07aba5dSTimm Baeder struct { 118a07aba5dSTimm Baeder float x,y; 119a07aba5dSTimm Baeder } a; 120a07aba5dSTimm Baeder int b; 121a07aba5dSTimm Baeder } Z; 122a07aba5dSTimm Baeder 123a07aba5dSTimm Baeder Z.a.y = 10; 124a07aba5dSTimm Baeder 125a07aba5dSTimm Baeder return Z.a.x; // both-note {{read of uninitialized object}} 126a07aba5dSTimm Baeder } 127a07aba5dSTimm Baeder static_assert(foo3() == 10); // both-error {{not an integral constant expression}} \ 128a07aba5dSTimm Baeder // both-note {{in call to}} 129a07aba5dSTimm Baeder 130a07aba5dSTimm Baeder constexpr int foo4() { 131a07aba5dSTimm Baeder union { 132a07aba5dSTimm Baeder struct { 133a07aba5dSTimm Baeder float x,y; 134a07aba5dSTimm Baeder } a; 135a07aba5dSTimm Baeder int b; 136a07aba5dSTimm Baeder } Z; 137a07aba5dSTimm Baeder 138a07aba5dSTimm Baeder Z.a.x = 100; 139a07aba5dSTimm Baeder Z.a.y = 10; 140a07aba5dSTimm Baeder 141a07aba5dSTimm Baeder return Z.a.x; 142a07aba5dSTimm Baeder } 143a07aba5dSTimm Baeder static_assert(foo4() == 100); 144a07aba5dSTimm Baeder } 145a07aba5dSTimm Baeder 146a07aba5dSTimm Baeder namespace IndirectFieldDecl { 147a07aba5dSTimm Baeder struct C { 148a07aba5dSTimm Baeder union { int a, b = 2, c; }; 149a07aba5dSTimm Baeder union { int d, e = 5, f; }; 150a07aba5dSTimm Baeder constexpr C() : a(1) {} 151a07aba5dSTimm Baeder }; 152a07aba5dSTimm Baeder static_assert(C().a == 1, ""); 153a07aba5dSTimm Baeder } 154a07aba5dSTimm Baeder 155a07aba5dSTimm Baeder namespace UnionDtor { 156a07aba5dSTimm Baeder 157a07aba5dSTimm Baeder union U { 158a07aba5dSTimm Baeder int *I; 159a07aba5dSTimm Baeder constexpr U(int *I) : I(I) {} 160a07aba5dSTimm Baeder constexpr ~U() { 161a07aba5dSTimm Baeder *I = 10; 162a07aba5dSTimm Baeder } 163a07aba5dSTimm Baeder }; 164a07aba5dSTimm Baeder 165a07aba5dSTimm Baeder constexpr int foo() { 166a07aba5dSTimm Baeder int a = 100; 167a07aba5dSTimm Baeder { 168a07aba5dSTimm Baeder U u(&a); 169a07aba5dSTimm Baeder } 170a07aba5dSTimm Baeder return a; 171a07aba5dSTimm Baeder } 172a07aba5dSTimm Baeder static_assert(foo() == 10); 173a07aba5dSTimm Baeder } 174a07aba5dSTimm Baeder 175a07aba5dSTimm Baeder namespace UnionMemberDtor { 176a07aba5dSTimm Baeder class UM { 177a07aba5dSTimm Baeder public: 178a07aba5dSTimm Baeder int &I; 179a07aba5dSTimm Baeder constexpr UM(int &I) : I(I) {} 180a07aba5dSTimm Baeder constexpr ~UM() { I = 200; } 181a07aba5dSTimm Baeder }; 182a07aba5dSTimm Baeder 183a07aba5dSTimm Baeder union U { 184a07aba5dSTimm Baeder UM um; 185a07aba5dSTimm Baeder constexpr U(int &I) : um(I) {} 186a07aba5dSTimm Baeder constexpr ~U() { 187a07aba5dSTimm Baeder } 188a07aba5dSTimm Baeder }; 189a07aba5dSTimm Baeder 190a07aba5dSTimm Baeder constexpr int foo() { 191a07aba5dSTimm Baeder int a = 100; 192a07aba5dSTimm Baeder { 193a07aba5dSTimm Baeder U u(a); 194a07aba5dSTimm Baeder } 195a07aba5dSTimm Baeder 196a07aba5dSTimm Baeder return a; 197a07aba5dSTimm Baeder } 198a07aba5dSTimm Baeder static_assert(foo() == 100); 199a07aba5dSTimm Baeder } 200a07aba5dSTimm Baeder 201a07aba5dSTimm Baeder namespace Nested { 202a07aba5dSTimm Baeder union U { 203a07aba5dSTimm Baeder int a; 204a07aba5dSTimm Baeder int b; 205a07aba5dSTimm Baeder }; 206a07aba5dSTimm Baeder 207a07aba5dSTimm Baeder union U2 { 208a07aba5dSTimm Baeder U u; 209a07aba5dSTimm Baeder U u2; 210a07aba5dSTimm Baeder int x; 211a07aba5dSTimm Baeder int y; 212a07aba5dSTimm Baeder }; 213a07aba5dSTimm Baeder 214df11ee21STimm Baeder constexpr int foo() { // both-error {{constexpr function never produces a constant expression}} 215a07aba5dSTimm Baeder U2 u; 216a07aba5dSTimm Baeder u.u.a = 10; 217df11ee21STimm Baeder int a = u.y; // both-note 2{{read of member 'y' of union with active member 'u' is not allowed in a constant expression}} 218a07aba5dSTimm Baeder 219a07aba5dSTimm Baeder return 1; 220a07aba5dSTimm Baeder } 221a07aba5dSTimm Baeder static_assert(foo() == 1); // both-error {{not an integral constant expression}} \ 222a07aba5dSTimm Baeder // both-note {{in call to}} 223a07aba5dSTimm Baeder 224a07aba5dSTimm Baeder constexpr int foo2() { 225a07aba5dSTimm Baeder U2 u; 226a07aba5dSTimm Baeder u.u.a = 10; 227a07aba5dSTimm Baeder return u.u.a; 228a07aba5dSTimm Baeder } 229a07aba5dSTimm Baeder static_assert(foo2() == 10); 230a07aba5dSTimm Baeder 231df11ee21STimm Baeder constexpr int foo3() { // both-error {{constexpr function never produces a constant expression}} 232a07aba5dSTimm Baeder U2 u; 233a07aba5dSTimm Baeder u.u.a = 10; 234df11ee21STimm Baeder 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}} 235a07aba5dSTimm Baeder 236a07aba5dSTimm Baeder return 1; 237a07aba5dSTimm Baeder } 238a07aba5dSTimm Baeder static_assert(foo3() == 1); // both-error {{not an integral constant expression}} \ 239a07aba5dSTimm Baeder // both-note {{in call to}} 240a07aba5dSTimm Baeder 241df11ee21STimm Baeder constexpr int foo4() { // both-error {{constexpr function never produces a constant expression}} 242a07aba5dSTimm Baeder U2 u; 243a07aba5dSTimm Baeder 244a07aba5dSTimm Baeder u.x = 10; 245a07aba5dSTimm Baeder 246df11ee21STimm Baeder return u.u.a; // both-note 2{{read of member 'u' of union with active member 'x' is not allowed in a constant expression}} 247a07aba5dSTimm Baeder } 248a07aba5dSTimm Baeder static_assert(foo4() == 1); // both-error {{not an integral constant expression}} \ 249a07aba5dSTimm Baeder // both-note {{in call to}} 250a07aba5dSTimm Baeder 251a07aba5dSTimm Baeder } 252a07aba5dSTimm Baeder 253a07aba5dSTimm Baeder 254a07aba5dSTimm Baeder namespace Zeroing { 255a07aba5dSTimm Baeder struct non_trivial_constructor { 256a07aba5dSTimm Baeder constexpr non_trivial_constructor() : x(100) {} 257a07aba5dSTimm Baeder int x; 258a07aba5dSTimm Baeder }; 259a07aba5dSTimm Baeder union U2 { 260a07aba5dSTimm Baeder int a{1000}; 261a07aba5dSTimm Baeder non_trivial_constructor b; 262a07aba5dSTimm Baeder }; 263a07aba5dSTimm Baeder 264a07aba5dSTimm Baeder static_assert(U2().b.x == 100, ""); // both-error {{not an integral constant expression}} \ 265a07aba5dSTimm Baeder // both-note {{read of member 'b' of union with active member 'a'}} 266a07aba5dSTimm Baeder 267a07aba5dSTimm Baeder union { int a; int b; } constexpr u1{}; 268a07aba5dSTimm Baeder static_assert(u1.a == 0, ""); 269a07aba5dSTimm Baeder static_assert(u1.b == 0, ""); // both-error {{not an integral constant expression}} \ 270a07aba5dSTimm Baeder // both-note {{read of member 'b' of union with active member 'a'}} 271a07aba5dSTimm Baeder 272a07aba5dSTimm Baeder union U { int a; int b; } constexpr u2 = U(); 273a07aba5dSTimm Baeder static_assert(u2.a == 0, ""); 274a07aba5dSTimm Baeder static_assert(u2.b == 0, ""); // both-error {{not an integral constant expression}} \ 275a07aba5dSTimm Baeder // both-note {{read of member 'b' of union with active member 'a'}} 276a07aba5dSTimm Baeder 277a07aba5dSTimm Baeder 278a07aba5dSTimm Baeder struct F {int x; int y; }; 279a07aba5dSTimm Baeder union { F a; int b; } constexpr u3{}; 280a07aba5dSTimm Baeder static_assert(u3.a.x == 0, ""); 281a07aba5dSTimm Baeder 282a07aba5dSTimm Baeder union U4 { F a; int b; } constexpr u4 = U4(); 283a07aba5dSTimm Baeder static_assert(u4.a.x == 0, ""); 284a07aba5dSTimm Baeder 285a07aba5dSTimm Baeder union { int a[5]; int b; } constexpr u5{}; 286a07aba5dSTimm Baeder static_assert(u5.a[0] == 0, ""); 287a07aba5dSTimm Baeder static_assert(u5.a[4] == 0, ""); 288a07aba5dSTimm Baeder static_assert(u5.b == 0, ""); // both-error {{not an integral constant expression}} \ 289a07aba5dSTimm Baeder // both-note {{read of member 'b' of union with active member 'a'}} 290a07aba5dSTimm Baeder 291a07aba5dSTimm Baeder union U6 { int a[5]; int b; } constexpr u6 = U6(); 292a07aba5dSTimm Baeder static_assert(u6.a[0] == 0, ""); 293a07aba5dSTimm Baeder static_assert(u6.a[4] == 0, ""); 294a07aba5dSTimm Baeder static_assert(u6.b == 0, ""); // both-error {{not an integral constant expression}} \ 295a07aba5dSTimm Baeder // both-note {{read of member 'b' of union with active member 'a'}} 296a07aba5dSTimm Baeder 297a07aba5dSTimm Baeder union UnionWithUnnamedBitfield { 298a07aba5dSTimm Baeder int : 3; 299a07aba5dSTimm Baeder int n; 300a07aba5dSTimm Baeder }; 301a07aba5dSTimm Baeder static_assert(UnionWithUnnamedBitfield().n == 0, ""); 302a07aba5dSTimm Baeder static_assert(UnionWithUnnamedBitfield{}.n == 0, ""); 303a07aba5dSTimm Baeder static_assert(UnionWithUnnamedBitfield{1}.n == 1, ""); 304a07aba5dSTimm Baeder } 305a07aba5dSTimm Baeder 306a07aba5dSTimm Baeder namespace IndirectField { 307a07aba5dSTimm Baeder struct S { 308a07aba5dSTimm Baeder struct { 309a07aba5dSTimm Baeder union { 310a07aba5dSTimm Baeder struct { 311a07aba5dSTimm Baeder int a; 312a07aba5dSTimm Baeder int b; 313a07aba5dSTimm Baeder }; 314a07aba5dSTimm Baeder int c; 315a07aba5dSTimm Baeder }; 316a07aba5dSTimm Baeder int d; 317a07aba5dSTimm Baeder }; 318a07aba5dSTimm Baeder union { 319a07aba5dSTimm Baeder int e; 320a07aba5dSTimm Baeder int f; 321a07aba5dSTimm Baeder }; 322a07aba5dSTimm Baeder constexpr S(int a, int b, int d, int e) : a(a), b(b), d(d), e(e) {} 323a07aba5dSTimm Baeder constexpr S(int c, int d, int f) : c(c), d(d), f(f) {} 324a07aba5dSTimm Baeder }; 325a07aba5dSTimm Baeder 326a07aba5dSTimm Baeder constexpr S s1(1,2,3,4); 327a07aba5dSTimm Baeder constexpr S s2(5, 6, 7); 328a07aba5dSTimm Baeder 329a07aba5dSTimm Baeder static_assert(s1.a == 1, ""); 330a07aba5dSTimm Baeder static_assert(s1.b == 2, ""); 331a07aba5dSTimm Baeder 332a07aba5dSTimm Baeder static_assert(s1.c == 0, ""); // both-error {{constant expression}} both-note {{union with active member}} 333a07aba5dSTimm Baeder static_assert(s1.d == 3, ""); 334a07aba5dSTimm Baeder static_assert(s1.e == 4, ""); 335a07aba5dSTimm Baeder static_assert(s1.f == 0, ""); // both-error {{constant expression}} both-note {{union with active member}} 336a07aba5dSTimm Baeder 337a07aba5dSTimm Baeder static_assert(s2.a == 0, ""); // both-error {{constant expression}} both-note {{union with active member}} 338a07aba5dSTimm Baeder static_assert(s2.b == 0, ""); // both-error {{constant expression}} both-note {{union with active member}} 339a07aba5dSTimm Baeder static_assert(s2.c == 5, ""); 340a07aba5dSTimm Baeder static_assert(s2.d == 6, ""); 341a07aba5dSTimm Baeder static_assert(s2.e == 0, ""); // both-error {{constant expression}} both-note {{union with active member}} 342a07aba5dSTimm Baeder static_assert(s2.f == 7, ""); 343a07aba5dSTimm Baeder } 344a07aba5dSTimm Baeder 345a07aba5dSTimm Baeder namespace CopyCtor { 346a07aba5dSTimm Baeder union U { 347a07aba5dSTimm Baeder int a; 348a07aba5dSTimm Baeder int b; 349a07aba5dSTimm Baeder }; 350a07aba5dSTimm Baeder 351a07aba5dSTimm Baeder constexpr U x = {42}; 352a07aba5dSTimm Baeder constexpr U y = x; 353a07aba5dSTimm Baeder static_assert(y.a == 42, ""); 354a07aba5dSTimm Baeder static_assert(y.b == 42, ""); // both-error {{constant expression}} \ 355a07aba5dSTimm Baeder // both-note {{'b' of union with active member 'a'}} 356a07aba5dSTimm Baeder } 357a07aba5dSTimm Baeder 358a07aba5dSTimm Baeder namespace UnionInBase { 359a07aba5dSTimm Baeder struct Base { 360a07aba5dSTimm Baeder int y; // both-note {{subobject declared here}} 361a07aba5dSTimm Baeder }; 362a07aba5dSTimm Baeder struct A : Base { 363a07aba5dSTimm Baeder int x; 364a07aba5dSTimm Baeder int arr[3]; 365a07aba5dSTimm Baeder union { int p, q; }; 366a07aba5dSTimm Baeder }; 367a07aba5dSTimm Baeder union B { 368a07aba5dSTimm Baeder A a; 369a07aba5dSTimm Baeder int b; 370a07aba5dSTimm Baeder }; 371a07aba5dSTimm Baeder constexpr int read_wrong_member_indirect() { // both-error {{never produces a constant}} 372a07aba5dSTimm Baeder B b = {.b = 1}; 373a07aba5dSTimm Baeder int *p = &b.a.y; 374a07aba5dSTimm Baeder return *p; // both-note 2{{read of member 'a' of union with active member 'b'}} 375a07aba5dSTimm Baeder 376a07aba5dSTimm Baeder } 377a07aba5dSTimm Baeder static_assert(read_wrong_member_indirect() == 1); // both-error {{not an integral constant expression}} \ 378a07aba5dSTimm Baeder // both-note {{in call to}} 379a07aba5dSTimm Baeder constexpr int read_uninitialized() { 380a07aba5dSTimm Baeder B b = {.b = 1}; 381a07aba5dSTimm Baeder int *p = &b.a.y; 382a07aba5dSTimm Baeder b.a.x = 1; 383a07aba5dSTimm Baeder return *p; // both-note {{read of uninitialized object}} 384a07aba5dSTimm Baeder } 385a07aba5dSTimm Baeder static_assert(read_uninitialized() == 0); // both-error {{constant}} \ 386a07aba5dSTimm Baeder // both-note {{in call}} 387a07aba5dSTimm Baeder constexpr int write_uninitialized() { 388a07aba5dSTimm Baeder B b = {.b = 1}; 389a07aba5dSTimm Baeder int *p = &b.a.y; 390a07aba5dSTimm Baeder b.a.x = 1; 391a07aba5dSTimm Baeder *p = 1; 392a07aba5dSTimm Baeder return *p; 393a07aba5dSTimm Baeder } 394a07aba5dSTimm Baeder 395a07aba5dSTimm Baeder constexpr B return_uninit() { 396a07aba5dSTimm Baeder B b = {.b = 1}; 397a07aba5dSTimm Baeder b.a.x = 2; 398a07aba5dSTimm Baeder return b; 399a07aba5dSTimm Baeder } 400a07aba5dSTimm Baeder constexpr B uninit = return_uninit(); // both-error {{constant expression}} \ 401a07aba5dSTimm Baeder // both-note {{subobject 'y' is not initialized}} 402a07aba5dSTimm Baeder static_assert(return_uninit().a.x == 2); 403a07aba5dSTimm Baeder } 404*ac857f9bSTimm Baeder 405*ac857f9bSTimm Baeder /// FIXME: Our diagnostic here is a little off. 406*ac857f9bSTimm Baeder namespace One { 407*ac857f9bSTimm Baeder struct A { long x; }; 408*ac857f9bSTimm Baeder 409*ac857f9bSTimm Baeder union U; 410*ac857f9bSTimm Baeder constexpr A foo(U *up); 411*ac857f9bSTimm Baeder union U { 412*ac857f9bSTimm Baeder A a = foo(this); // both-note {{in call to 'foo(&u)'}} 413*ac857f9bSTimm Baeder int y; 414*ac857f9bSTimm Baeder }; 415*ac857f9bSTimm Baeder 416*ac857f9bSTimm Baeder constexpr A foo(U *up) { 417*ac857f9bSTimm Baeder return {up->y}; // both-note {{read of member 'y' of union}} 418*ac857f9bSTimm Baeder } 419*ac857f9bSTimm Baeder 420*ac857f9bSTimm Baeder constinit U u = {}; // both-error {{constant init}} \ 421*ac857f9bSTimm Baeder // both-note {{constinit}} 422*ac857f9bSTimm Baeder } 423*ac857f9bSTimm Baeder 424a07aba5dSTimm Baeder #endif 425