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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits