[clang] 0fcb26c - [clang] Fix __try/__finally blocks in C++ constructors.
Eli Friedman via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 16 15:15:20 PST 2022
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 at 0@?0use_seh_in_constructor@@"
+
static int my_unique_global;
extern "C" inline void use_seh_in_inline_func() {
More information about the cfe-commits
mailing list