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;
25
25
namespace clang {
26
26
namespace interp {
27
27
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
+
28
35
static bool refersToUnion (const Expr *E) {
29
36
for (;;) {
30
37
if (const auto *ME = dyn_cast<MemberExpr>(E)) {
31
38
if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl ());
32
- FD && FD->getParent ()->isUnion ())
39
+ FD && FD->getParent ()->isUnion () && hasTrivialDefaultCtorParent (FD) )
33
40
return true ;
34
41
E = ME->getBase ();
35
42
continue ;
Original file line number Diff line number Diff line change @@ -861,6 +861,61 @@ namespace CopyCtorMutable {
861
861
// both-note {{in call}}
862
862
}
863
863
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
+
864
919
#endif
865
920
866
921
namespace AddressComparison {
You can’t perform that action at this time.
0 commit comments