https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/110087
None >From d54a46d9ccc3eed3be0d319f26c49f069a68a9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Thu, 26 Sep 2024 09:41:33 +0200 Subject: [PATCH] [clang][bytecode] Don't call dtors of anonymous unions --- clang/lib/AST/ByteCode/Compiler.cpp | 7 +++++++ clang/lib/AST/ByteCode/Record.cpp | 3 ++- clang/lib/AST/ByteCode/Record.h | 4 ++++ clang/test/AST/ByteCode/cxx23.cpp | 31 +++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index e54b6568d7060b..6e3ea6bd070bc1 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -5302,6 +5302,9 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) { } for (const Record::Base &Base : llvm::reverse(R->bases())) { + if (Base.R->isAnonymousUnion()) + continue; + if (!this->emitGetPtrBase(Base.Offset, SourceInfo{})) return false; if (!this->emitRecordDestruction(Base.R)) @@ -6147,6 +6150,7 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS, template <class Emitter> bool Compiler<Emitter>::emitRecordDestruction(const Record *R) { assert(R); + assert(!R->isAnonymousUnion()); const CXXDestructorDecl *Dtor = R->getDestructor(); if (!Dtor || Dtor->isTrivial()) return true; @@ -6202,6 +6206,9 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc) { } assert(Desc->ElemRecord); + if (Desc->ElemRecord->isAnonymousUnion()) + return true; + return this->emitRecordDestruction(Desc->ElemRecord); } diff --git a/clang/lib/AST/ByteCode/Record.cpp b/clang/lib/AST/ByteCode/Record.cpp index ec1b55da347af6..0c06bec7e5508e 100644 --- a/clang/lib/AST/ByteCode/Record.cpp +++ b/clang/lib/AST/ByteCode/Record.cpp @@ -16,7 +16,8 @@ Record::Record(const RecordDecl *Decl, BaseList &&SrcBases, FieldList &&SrcFields, VirtualBaseList &&SrcVirtualBases, unsigned VirtualSize, unsigned BaseSize) : Decl(Decl), Bases(std::move(SrcBases)), Fields(std::move(SrcFields)), - BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()) { + BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()), + IsAnonymousUnion(IsUnion && Decl->isAnonymousStructOrUnion()) { for (Base &V : SrcVirtualBases) VirtualBases.push_back({V.Decl, V.Offset + BaseSize, V.Desc, V.R}); diff --git a/clang/lib/AST/ByteCode/Record.h b/clang/lib/AST/ByteCode/Record.h index 83e15b125f77a9..7a5c482e4efccd 100644 --- a/clang/lib/AST/ByteCode/Record.h +++ b/clang/lib/AST/ByteCode/Record.h @@ -54,6 +54,8 @@ class Record final { const std::string getName() const; /// Checks if the record is a union. bool isUnion() const { return IsUnion; } + /// Checks if the record is an anonymous union. + bool isAnonymousUnion() const { return IsAnonymousUnion; } /// Returns the size of the record. unsigned getSize() const { return BaseSize; } /// Returns the full size of the record, including records. @@ -134,6 +136,8 @@ class Record final { unsigned VirtualSize; /// If this record is a union. bool IsUnion; + /// If this is an anonymous union. + bool IsAnonymousUnion; }; } // namespace interp diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp index 756eec5b825605..9d7e9d753e6d2f 100644 --- a/clang/test/AST/ByteCode/cxx23.cpp +++ b/clang/test/AST/ByteCode/cxx23.cpp @@ -238,3 +238,34 @@ namespace TwosComplementShifts { static_assert(-3 >> 1 == -2); static_assert(-7 >> 1 == -4); } + +namespace AnonUnionDtor { + struct A { + A (); + ~A(); + }; + + template <class T> + struct opt + { + union { // all20-note {{is not literal}} + char c; + T data; + }; + + constexpr opt() {} + + constexpr ~opt() { + if (engaged) + data.~T(); + } + + bool engaged = false; + }; + + consteval void foo() { + opt<A> a; // all20-error {{variable of non-literal type}} + } + + void bar() { foo(); } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits