[clang] 86691f8 - [clang][Interp] Do not call dtors of union members (#102739)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 10 04:45:34 PDT 2024
Author: Timm Baeder
Date: 2024-08-10T13:45:30+02:00
New Revision: 86691f8d7e86176db7409ccafb7a79964221720a
URL: https://github.com/llvm/llvm-project/commit/86691f8d7e86176db7409ccafb7a79964221720a
DIFF: https://github.com/llvm/llvm-project/commit/86691f8d7e86176db7409ccafb7a79964221720a.diff
LOG: [clang][Interp] Do not call dtors of union members (#102739)
Added:
Modified:
clang/lib/AST/Interp/Compiler.cpp
clang/test/AST/Interp/unions.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index 0d72e33c1c7d2..d0e4d409b6580 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -5552,22 +5552,21 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
template <class Emitter>
bool Compiler<Emitter>::emitRecordDestruction(const Record *R) {
assert(R);
- // First, destroy all fields.
- for (const Record::Field &Field : llvm::reverse(R->fields())) {
- const Descriptor *D = Field.Desc;
- if (!D->isPrimitive() && !D->isPrimitiveArray()) {
- if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
- return false;
- if (!this->emitDestruction(D))
- return false;
- if (!this->emitPopPtr(SourceInfo{}))
- return false;
+ if (!R->isUnion()) {
+ // First, destroy all fields.
+ for (const Record::Field &Field : llvm::reverse(R->fields())) {
+ const Descriptor *D = Field.Desc;
+ if (!D->isPrimitive() && !D->isPrimitiveArray()) {
+ if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
+ return false;
+ if (!this->emitDestruction(D))
+ return false;
+ if (!this->emitPopPtr(SourceInfo{}))
+ return false;
+ }
}
}
- // FIXME: Unions need to be handled
diff erently here. We don't want to
- // call the destructor of its members.
-
// Now emit the destructor and recurse into base classes.
if (const CXXDestructorDecl *Dtor = R->getDestructor();
Dtor && !Dtor->isTrivial()) {
diff --git a/clang/test/AST/Interp/unions.cpp b/clang/test/AST/Interp/unions.cpp
index d615b3584b30b..b0b279831405d 100644
--- a/clang/test/AST/Interp/unions.cpp
+++ b/clang/test/AST/Interp/unions.cpp
@@ -152,4 +152,50 @@ namespace IndirectFieldDecl {
};
static_assert(C().a == 1, "");
}
+
+namespace UnionDtor {
+
+ union U {
+ int *I;
+ constexpr U(int *I) : I(I) {}
+ constexpr ~U() {
+ *I = 10;
+ }
+ };
+
+ constexpr int foo() {
+ int a = 100;
+ {
+ U u(&a);
+ }
+ return a;
+ }
+ static_assert(foo() == 10);
+}
+
+namespace UnionMemberDtor {
+ class UM {
+ public:
+ int &I;
+ constexpr UM(int &I) : I(I) {}
+ constexpr ~UM() { I = 200; }
+ };
+
+ union U {
+ UM um;
+ constexpr U(int &I) : um(I) {}
+ constexpr ~U() {
+ }
+ };
+
+ constexpr int foo() {
+ int a = 100;
+ {
+ U u(a);
+ }
+
+ return a;
+ }
+ static_assert(foo() == 100);
+}
#endif
More information about the cfe-commits
mailing list