[clang] [clang][Interp] Do not call dtors of union members (PR #102739)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 10 07:43:11 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/102739.diff
2 Files Affected:
- (modified) clang/lib/AST/Interp/Compiler.cpp (+12-13)
- (modified) clang/test/AST/Interp/unions.cpp (+46)
``````````diff
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 differently 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
``````````
</details>
https://github.com/llvm/llvm-project/pull/102739
More information about the cfe-commits
mailing list