-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][Interp] Do not call dtors of union members #102739
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/134/builds/3229 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/66/builds/2700 Here is the relevant piece of the build log for the reference:
|
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesFull diff: https://github.com/llvm/llvm-project/pull/102739.diff 2 Files Affected:
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
|
No description provided.