Author: Eli Friedman Date: 2022-11-16T15:13:33-08:00 New Revision: 0fcb26c5b6487bf9b31670122f8c931ac020bb34
URL: https://github.com/llvm/llvm-project/commit/0fcb26c5b6487bf9b31670122f8c931ac020bb34 DIFF: https://github.com/llvm/llvm-project/commit/0fcb26c5b6487bf9b31670122f8c931ac020bb34.diff LOG: [clang] Fix __try/__finally blocks in C++ constructors. We were crashing trying to convert a GlobalDecl from a CXXConstructorDecl. Instead of trying to do that conversion, just pass down the original GlobalDecl. I think we could actually compute the correct constructor/destructor kind from the context, given the way Microsoft mangling works, but it's simpler to just pass through the correct constructor/destructor kind. Differential Revision: https://reviews.llvm.org/D136776 Added: Modified: clang/include/clang/AST/Mangle.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CGException.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/CodeGenCXX/exceptions-seh.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h index a22ed5ab72405..80e7a9df01b55 100644 --- a/clang/include/clang/AST/Mangle.h +++ b/clang/include/clang/AST/Mangle.h @@ -166,10 +166,10 @@ class MangleContext { virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &) = 0; - virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, + virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out) = 0; - virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, + virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out) = 0; /// Generates a unique string for an externally visible type for use with TBAA diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index c95ca68397430..d811196d6f24a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -118,9 +118,9 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext { void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out) override; void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &Out) override; - void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, + void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out) override; - void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, + void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out) override; void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &) override; void mangleItaniumThreadLocalWrapper(const VarDecl *D, @@ -6430,23 +6430,25 @@ void ItaniumMangleContextImpl::mangleDynamicStermFinalizer(const VarDecl *D, } void ItaniumMangleContextImpl::mangleSEHFilterExpression( - const NamedDecl *EnclosingDecl, raw_ostream &Out) { + GlobalDecl EnclosingDecl, raw_ostream &Out) { CXXNameMangler Mangler(*this, Out); Mangler.getStream() << "__filt_"; - if (shouldMangleDeclName(EnclosingDecl)) + auto *EnclosingFD = cast<FunctionDecl>(EnclosingDecl.getDecl()); + if (shouldMangleDeclName(EnclosingFD)) Mangler.mangle(EnclosingDecl); else - Mangler.getStream() << EnclosingDecl->getName(); + Mangler.getStream() << EnclosingFD->getName(); } void ItaniumMangleContextImpl::mangleSEHFinallyBlock( - const NamedDecl *EnclosingDecl, raw_ostream &Out) { + GlobalDecl EnclosingDecl, raw_ostream &Out) { CXXNameMangler Mangler(*this, Out); Mangler.getStream() << "__fin_"; - if (shouldMangleDeclName(EnclosingDecl)) + auto *EnclosingFD = cast<FunctionDecl>(EnclosingDecl.getDecl()); + if (shouldMangleDeclName(EnclosingFD)) Mangler.mangle(EnclosingDecl); else - Mangler.getStream() << EnclosingDecl->getName(); + Mangler.getStream() << EnclosingFD->getName(); } void ItaniumMangleContextImpl::mangleItaniumThreadLocalInit(const VarDecl *D, diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index bc4dd66433b52..4408a8318e894 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -142,8 +142,8 @@ class MicrosoftMangleContextImpl : public MicrosoftMangleContext { llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator; llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier; llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds; - llvm::DenseMap<const NamedDecl *, unsigned> SEHFilterIds; - llvm::DenseMap<const NamedDecl *, unsigned> SEHFinallyIds; + llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds; + llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds; SmallString<16> AnonymousNamespaceHash; public: @@ -201,9 +201,9 @@ class MicrosoftMangleContextImpl : public MicrosoftMangleContext { void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override; void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out) override; - void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, + void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out) override; - void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, + void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out) override; void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override; bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { @@ -3730,7 +3730,7 @@ void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator( } void MicrosoftMangleContextImpl::mangleSEHFilterExpression( - const NamedDecl *EnclosingDecl, raw_ostream &Out) { + GlobalDecl EnclosingDecl, raw_ostream &Out) { msvc_hashing_ostream MHO(Out); MicrosoftCXXNameMangler Mangler(*this, MHO); // The function body is in the same comdat as the function with the handler, @@ -3742,7 +3742,7 @@ void MicrosoftMangleContextImpl::mangleSEHFilterExpression( } void MicrosoftMangleContextImpl::mangleSEHFinallyBlock( - const NamedDecl *EnclosingDecl, raw_ostream &Out) { + GlobalDecl EnclosingDecl, raw_ostream &Out) { msvc_hashing_ostream MHO(Out); MicrosoftCXXNameMangler Mangler(*this, MHO); // The function body is in the same comdat as the function with the handler, diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 93a8e317e72f4..35327d23d8547 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -249,7 +249,7 @@ const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) { // For outlined finallys and filters, use the SEH personality in case they // contain more SEH. This mostly only affects finallys. Filters could // hypothetically use gnu statement expressions to sneak in nested SEH. - FD = FD ? FD : CGF.CurSEHParent; + FD = FD ? FD : CGF.CurSEHParent.getDecl(); return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD)); } @@ -2005,7 +2005,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF, SmallString<128> Name; { llvm::raw_svector_ostream OS(Name); - const NamedDecl *ParentSEHFn = ParentCGF.CurSEHParent; + GlobalDecl ParentSEHFn = ParentCGF.CurSEHParent; assert(ParentSEHFn && "No CurSEHParent!"); MangleContext &Mangler = CGM.getCXXABI().getMangleContext(); if (IsFilter) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 62e58b34130e3..9a1ae23dcbd97 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -701,7 +701,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, CurCodeDecl = D; const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); if (FD && FD->usesSEHTry()) - CurSEHParent = FD; + CurSEHParent = GD; CurFuncDecl = (D ? D->getNonClosureContext() : nullptr); FnRetTy = RetTy; CurFn = Fn; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index aece9bd4dbe1e..7390508052853 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -539,7 +539,7 @@ class CodeGenFunction : public CodeGenTypeCache { /// potentially set the return value. bool SawAsmBlock = false; - const NamedDecl *CurSEHParent = nullptr; + GlobalDecl CurSEHParent; /// True if the current function is an outlined SEH helper. This can be a /// finally block or filter expression. @@ -2021,7 +2021,7 @@ class CodeGenFunction : public CodeGenTypeCache { return getInvokeDestImpl(); } - bool currentFunctionUsesSEHTry() const { return CurSEHParent != nullptr; } + bool currentFunctionUsesSEHTry() const { return !!CurSEHParent; } const TargetInfo &getTarget() const { return Target; } llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); } diff --git a/clang/test/CodeGenCXX/exceptions-seh.cpp b/clang/test/CodeGenCXX/exceptions-seh.cpp index 421b6a4b8e5cc..bb374dd1f5bd5 100644 --- a/clang/test/CodeGenCXX/exceptions-seh.cpp +++ b/clang/test/CodeGenCXX/exceptions-seh.cpp @@ -121,6 +121,15 @@ void use_seh_in_lambda() { // CHECK: invoke void @might_throw() #[[NOINLINE]] // CHECK: catchpad +class use_seh_in_constructor { use_seh_in_constructor(); }; +use_seh_in_constructor::use_seh_in_constructor(){ + __try { + } __finally { + } +} + +// CHECK: define internal void @"?fin$0@0@?0use_seh_in_constructor@@" + static int my_unique_global; extern "C" inline void use_seh_in_inline_func() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits