[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
This commit is contained in:
parent
55f56cdc33
commit
0fcb26c5b6
|
@ -166,10 +166,10 @@ public:
|
|||
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
|
||||
|
|
|
@ -118,9 +118,9 @@ public:
|
|||
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,
|
||||
|
|
|
@ -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 @@ public:
|
|||
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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -539,7 +539,7 @@ public:
|
|||
/// 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 @@ public:
|
|||
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(); }
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue