[clang] Mark union member destructors referenced (PR #128866)

Maurice Heumann via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 26 05:32:21 PST 2025


https://github.com/momo5502 updated https://github.com/llvm/llvm-project/pull/128866

>From 484ff7a53ab700fda30ee90f739bb2573f41c851 Mon Sep 17 00:00:00 2001
From: Maurice Heumann <maurice.heumann at wibu.com>
Date: Wed, 26 Feb 2025 08:37:04 +0100
Subject: [PATCH 1/2] Mark union member destructors referenced

---
 clang/lib/Sema/SemaDeclCXX.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 664d48ccbc382..ce7927dedd96b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -5764,7 +5764,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
                                              CXXRecordDecl *ClassDecl) {
   // Ignore dependent contexts. Also ignore unions, since their members never
   // have destructors implicitly called.
-  if (ClassDecl->isDependentContext() || ClassDecl->isUnion())
+  if (ClassDecl->isDependentContext() /*|| ClassDecl->isUnion()*/)
     return;
 
   // FIXME: all the access-control diagnostics are positioned on the
@@ -5793,8 +5793,10 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
     if (FieldClassDecl->hasIrrelevantDestructor())
       continue;
     // The destructor for an implicit anonymous union member is never invoked.
-    if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
+    if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) {
+      MarkBaseAndMemberDestructorsReferenced(Location, FieldClassDecl);
       continue;
+    }
 
     CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
     // Dtor might still be missing, e.g because it's invalid.

>From 448d01dc91a4cb79250efd43f52da5caa18ed6b5 Mon Sep 17 00:00:00 2001
From: Maurice Heumann <maurice.heumann at wibu.com>
Date: Wed, 26 Feb 2025 14:31:47 +0100
Subject: [PATCH 2/2] Only instantiate destructors via a constructor

---
 clang/include/clang/Sema/Sema.h | 2 +-
 clang/lib/Sema/SemaDecl.cpp     | 2 +-
 clang/lib/Sema/SemaDeclCXX.cpp  | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 476abe86cb2d2..c2e6006c06a77 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5430,7 +5430,7 @@ class Sema final : public SemaBase {
   /// mark all the non-trivial destructors of its members and bases as
   /// referenced.
   void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
-                                              CXXRecordDecl *Record);
+                                              CXXRecordDecl *Record, bool AllowUnionMembers);
 
   /// Mark destructors of virtual bases of this class referenced. In the Itanium
   /// C++ ABI, this is done when emitting a destructor for any non-abstract
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 285bd27a35a76..d546acb238583 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16464,7 +16464,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
           CheckDestructor(Destructor);
 
         MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
-                                               Destructor->getParent());
+                                               Destructor->getParent(), false);
       }
 
       // If any errors have occurred, clear out any temporaries that may have
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ce7927dedd96b..a9f17f1981b33 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -5454,7 +5454,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
     // Constructors implicitly reference the base and member
     // destructors.
     MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(),
-                                           Constructor->getParent());
+                                           Constructor->getParent(), true);
   }
 
   return HadError;
@@ -5761,7 +5761,7 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
 
 void
 Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
-                                             CXXRecordDecl *ClassDecl) {
+                                             CXXRecordDecl *ClassDecl, bool AllowUnionMembers) {
   // Ignore dependent contexts. Also ignore unions, since their members never
   // have destructors implicitly called.
   if (ClassDecl->isDependentContext() /*|| ClassDecl->isUnion()*/)
@@ -5794,7 +5794,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
       continue;
     // The destructor for an implicit anonymous union member is never invoked.
     if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) {
-      MarkBaseAndMemberDestructorsReferenced(Location, FieldClassDecl);
+      MarkBaseAndMemberDestructorsReferenced(Location, FieldClassDecl,  AllowUnionMembers && !ClassDecl->isUnion());
       continue;
     }
 
@@ -14305,7 +14305,7 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
   Scope.addContextNote(CurrentLocation);
 
   MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
-                                         Destructor->getParent());
+                                         Destructor->getParent(), false);
 
   if (CheckDestructor(Destructor)) {
     Destructor->setInvalidDecl();



More information about the cfe-commits mailing list