File tree Expand file tree Collapse file tree 2 files changed +63
-1
lines changed Expand file tree Collapse file tree 2 files changed +63
-1
lines changed Original file line number Diff line number Diff line change @@ -25,11 +25,18 @@ using APSInt = llvm::APSInt;
2525namespace clang {
2626namespace interp {
2727
28+ static bool hasTrivialDefaultCtorParent (const FieldDecl *FD) {
29+ assert (FD);
30+ assert (FD->getParent ()->isUnion ());
31+ const auto *CXXRD = dyn_cast<CXXRecordDecl>(FD->getParent ());
32+ return !CXXRD || CXXRD->hasTrivialDefaultConstructor ();
33+ }
34+
2835static bool refersToUnion (const Expr *E) {
2936 for (;;) {
3037 if (const auto *ME = dyn_cast<MemberExpr>(E)) {
3138 if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl ());
32- FD && FD->getParent ()->isUnion ())
39+ FD && FD->getParent ()->isUnion () && hasTrivialDefaultCtorParent (FD) )
3340 return true ;
3441 E = ME->getBase ();
3542 continue ;
Original file line number Diff line number Diff line change @@ -861,6 +861,61 @@ namespace CopyCtorMutable {
861861 // both-note {{in call}}
862862}
863863
864+
865+ namespace NonTrivialCtor {
866+ struct A { int x = 1 ; constexpr int f () { return 1 ; } };
867+ struct B : A { int y = 1 ; constexpr int g () { return 2 ; } };
868+ struct C {
869+ int x;
870+ constexpr virtual int f () = 0;
871+ };
872+ struct D : C {
873+ int y;
874+ constexpr virtual int f () override { return 3 ; }
875+ };
876+
877+ union U {
878+ int n;
879+ B b;
880+ D d;
881+ };
882+
883+ consteval int test (int which) {
884+ if (which == 0 ) {}
885+
886+ U u{.n = 5 };
887+ assert_active (u);
888+ assert_active (u.n );
889+ assert_inactive (u.b );
890+
891+ switch (which) {
892+ case 0 :
893+ u.b .x = 10 ; // both-note {{assignment to member 'b' of union with active member 'n'}}
894+ return u.b .f ();
895+ case 1 :
896+ u.b .y = 10 ; // both-note {{assignment to member 'b' of union with active member 'n'}}
897+ return u.b .g ();
898+ case 2 :
899+ u.d .x = 10 ; // both-note {{assignment to member 'd' of union with active member 'n'}}
900+ return u.d .f ();
901+ case 3 :
902+ u.d .y = 10 ; // both-note {{assignment to member 'd' of union with active member 'n'}}
903+ return u.d .f ();
904+ }
905+
906+ return 1 ;
907+ }
908+ static_assert (test(0 )); // both-error {{not an integral constant expression}} \
909+ // both-note {{in call}}
910+ static_assert (test(1 )); // both-error {{not an integral constant expression}} \
911+ // both-note {{in call}}
912+ static_assert (test(2 )); // both-error {{not an integral constant expression}} \
913+ // both-note {{in call}}
914+ static_assert (test(3 )); // both-error {{not an integral constant expression}} \
915+ // both-note {{in call}}
916+
917+ }
918+
864919#endif
865920
866921namespace AddressComparison {
You can’t perform that action at this time.
0 commit comments