Skip to content

Commit 0fcb26c

Browse files
committed
[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
1 parent 55f56cd commit 0fcb26c

File tree

7 files changed

+32
-21
lines changed

7 files changed

+32
-21
lines changed

clang/include/clang/AST/Mangle.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ class MangleContext {
166166
virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
167167
raw_ostream &) = 0;
168168

169-
virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
169+
virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
170170
raw_ostream &Out) = 0;
171171

172-
virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
172+
virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
173173
raw_ostream &Out) = 0;
174174

175175
/// Generates a unique string for an externally visible type for use with TBAA

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
118118
void mangleDynamicAtExitDestructor(const VarDecl *D,
119119
raw_ostream &Out) override;
120120
void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &Out) override;
121-
void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
121+
void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
122122
raw_ostream &Out) override;
123-
void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
123+
void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
124124
raw_ostream &Out) override;
125125
void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &) override;
126126
void mangleItaniumThreadLocalWrapper(const VarDecl *D,
@@ -6430,23 +6430,25 @@ void ItaniumMangleContextImpl::mangleDynamicStermFinalizer(const VarDecl *D,
64306430
}
64316431

64326432
void ItaniumMangleContextImpl::mangleSEHFilterExpression(
6433-
const NamedDecl *EnclosingDecl, raw_ostream &Out) {
6433+
GlobalDecl EnclosingDecl, raw_ostream &Out) {
64346434
CXXNameMangler Mangler(*this, Out);
64356435
Mangler.getStream() << "__filt_";
6436-
if (shouldMangleDeclName(EnclosingDecl))
6436+
auto *EnclosingFD = cast<FunctionDecl>(EnclosingDecl.getDecl());
6437+
if (shouldMangleDeclName(EnclosingFD))
64376438
Mangler.mangle(EnclosingDecl);
64386439
else
6439-
Mangler.getStream() << EnclosingDecl->getName();
6440+
Mangler.getStream() << EnclosingFD->getName();
64406441
}
64416442

64426443
void ItaniumMangleContextImpl::mangleSEHFinallyBlock(
6443-
const NamedDecl *EnclosingDecl, raw_ostream &Out) {
6444+
GlobalDecl EnclosingDecl, raw_ostream &Out) {
64446445
CXXNameMangler Mangler(*this, Out);
64456446
Mangler.getStream() << "__fin_";
6446-
if (shouldMangleDeclName(EnclosingDecl))
6447+
auto *EnclosingFD = cast<FunctionDecl>(EnclosingDecl.getDecl());
6448+
if (shouldMangleDeclName(EnclosingFD))
64476449
Mangler.mangle(EnclosingDecl);
64486450
else
6449-
Mangler.getStream() << EnclosingDecl->getName();
6451+
Mangler.getStream() << EnclosingFD->getName();
64506452
}
64516453

64526454
void ItaniumMangleContextImpl::mangleItaniumThreadLocalInit(const VarDecl *D,

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
142142
llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
143143
llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
144144
llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
145-
llvm::DenseMap<const NamedDecl *, unsigned> SEHFilterIds;
146-
llvm::DenseMap<const NamedDecl *, unsigned> SEHFinallyIds;
145+
llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
146+
llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
147147
SmallString<16> AnonymousNamespaceHash;
148148

149149
public:
@@ -201,9 +201,9 @@ class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
201201
void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
202202
void mangleDynamicAtExitDestructor(const VarDecl *D,
203203
raw_ostream &Out) override;
204-
void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
204+
void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
205205
raw_ostream &Out) override;
206-
void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
206+
void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
207207
raw_ostream &Out) override;
208208
void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
209209
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
@@ -3730,7 +3730,7 @@ void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
37303730
}
37313731

37323732
void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
3733-
const NamedDecl *EnclosingDecl, raw_ostream &Out) {
3733+
GlobalDecl EnclosingDecl, raw_ostream &Out) {
37343734
msvc_hashing_ostream MHO(Out);
37353735
MicrosoftCXXNameMangler Mangler(*this, MHO);
37363736
// The function body is in the same comdat as the function with the handler,
@@ -3742,7 +3742,7 @@ void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
37423742
}
37433743

37443744
void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
3745-
const NamedDecl *EnclosingDecl, raw_ostream &Out) {
3745+
GlobalDecl EnclosingDecl, raw_ostream &Out) {
37463746
msvc_hashing_ostream MHO(Out);
37473747
MicrosoftCXXNameMangler Mangler(*this, MHO);
37483748
// The function body is in the same comdat as the function with the handler,

clang/lib/CodeGen/CGException.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {
249249
// For outlined finallys and filters, use the SEH personality in case they
250250
// contain more SEH. This mostly only affects finallys. Filters could
251251
// hypothetically use gnu statement expressions to sneak in nested SEH.
252-
FD = FD ? FD : CGF.CurSEHParent;
252+
FD = FD ? FD : CGF.CurSEHParent.getDecl();
253253
return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD));
254254
}
255255

@@ -2005,7 +2005,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
20052005
SmallString<128> Name;
20062006
{
20072007
llvm::raw_svector_ostream OS(Name);
2008-
const NamedDecl *ParentSEHFn = ParentCGF.CurSEHParent;
2008+
GlobalDecl ParentSEHFn = ParentCGF.CurSEHParent;
20092009
assert(ParentSEHFn && "No CurSEHParent!");
20102010
MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
20112011
if (IsFilter)

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
701701
CurCodeDecl = D;
702702
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
703703
if (FD && FD->usesSEHTry())
704-
CurSEHParent = FD;
704+
CurSEHParent = GD;
705705
CurFuncDecl = (D ? D->getNonClosureContext() : nullptr);
706706
FnRetTy = RetTy;
707707
CurFn = Fn;

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ class CodeGenFunction : public CodeGenTypeCache {
539539
/// potentially set the return value.
540540
bool SawAsmBlock = false;
541541

542-
const NamedDecl *CurSEHParent = nullptr;
542+
GlobalDecl CurSEHParent;
543543

544544
/// True if the current function is an outlined SEH helper. This can be a
545545
/// finally block or filter expression.
@@ -2021,7 +2021,7 @@ class CodeGenFunction : public CodeGenTypeCache {
20212021
return getInvokeDestImpl();
20222022
}
20232023

2024-
bool currentFunctionUsesSEHTry() const { return CurSEHParent != nullptr; }
2024+
bool currentFunctionUsesSEHTry() const { return !!CurSEHParent; }
20252025

20262026
const TargetInfo &getTarget() const { return Target; }
20272027
llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); }

clang/test/CodeGenCXX/exceptions-seh.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@ void use_seh_in_lambda() {
121121
// CHECK: invoke void @might_throw() #[[NOINLINE]]
122122
// CHECK: catchpad
123123

124+
class use_seh_in_constructor { use_seh_in_constructor(); };
125+
use_seh_in_constructor::use_seh_in_constructor(){
126+
__try {
127+
} __finally {
128+
}
129+
}
130+
131+
// CHECK: define internal void @"?fin$0@0@?0use_seh_in_constructor@@"
132+
124133
static int my_unique_global;
125134

126135
extern "C" inline void use_seh_in_inline_func() {

0 commit comments

Comments
 (0)