summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGException.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGException.cpp')
-rw-r--r--clang/lib/CodeGen/CGException.cpp52
1 files changed, 38 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 1a20403e84e..255cb841c86 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -601,8 +601,8 @@ CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {
dispatchBlock = getTerminateHandler();
break;
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd unnecessary for Itanium!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd unnecessary for Itanium!");
}
scope.setCachedEHDispatchBlock(dispatchBlock);
}
@@ -645,8 +645,8 @@ CodeGenFunction::getMSVCDispatchBlock(EHScopeStack::stable_iterator SI) {
DispatchBlock->setName("terminate");
break;
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd dispatch block missing!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd dispatch block missing!");
}
EHS.setCachedEHDispatchBlock(DispatchBlock);
return DispatchBlock;
@@ -662,7 +662,7 @@ static bool isNonEHScope(const EHScope &S) {
case EHScope::Filter:
case EHScope::Catch:
case EHScope::Terminate:
- case EHScope::CatchEnd:
+ case EHScope::PadEnd:
return false;
}
@@ -721,8 +721,8 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
case EHScope::Terminate:
return getTerminateLandingPad();
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd unnecessary for Itanium!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd unnecessary for Itanium!");
case EHScope::Catch:
case EHScope::Cleanup:
@@ -790,8 +790,8 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
case EHScope::Catch:
break;
- case EHScope::CatchEnd:
- llvm_unreachable("CatchEnd unnecessary for Itanium!");
+ case EHScope::PadEnd:
+ llvm_unreachable("PadEnd unnecessary for Itanium!");
}
EHCatchScope &catchScope = cast<EHCatchScope>(*I);
@@ -1028,7 +1028,7 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
isa<CXXConstructorDecl>(CurCodeDecl);
if (CatchEndBlockBB)
- EHStack.pushCatchEnd(CatchEndBlockBB);
+ EHStack.pushPadEnd(CatchEndBlockBB);
// Perversely, we emit the handlers backwards precisely because we
// want them to appear in source order. In all of these cases, the
@@ -1083,7 +1083,7 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
EmitBlock(ContBB);
incrementProfileCounter(&S);
if (CatchEndBlockBB)
- EHStack.popCatchEnd();
+ EHStack.popPadEnd();
}
namespace {
@@ -1397,8 +1397,10 @@ void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
namespace {
struct PerformSEHFinally final : EHScopeStack::Cleanup {
llvm::Function *OutlinedFinally;
- PerformSEHFinally(llvm::Function *OutlinedFinally)
- : OutlinedFinally(OutlinedFinally) {}
+ EHScopeStack::stable_iterator EnclosingScope;
+ PerformSEHFinally(llvm::Function *OutlinedFinally,
+ EHScopeStack::stable_iterator EnclosingScope)
+ : OutlinedFinally(OutlinedFinally), EnclosingScope(EnclosingScope) {}
void Emit(CodeGenFunction &CGF, Flags F) override {
ASTContext &Context = CGF.getContext();
@@ -1423,7 +1425,28 @@ struct PerformSEHFinally final : EHScopeStack::Cleanup {
CGM.getTypes().arrangeFreeFunctionCall(Args, FPT,
/*chainCall=*/false);
+ // If this is the normal cleanup or using the old EH IR, just emit the call.
+ if (!F.isForEHCleanup() || !CGM.getCodeGenOpts().NewMSEH) {
+ CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
+ return;
+ }
+
+ // Build a cleanupendpad to unwind through.
+ llvm::BasicBlock *CleanupBB = CGF.Builder.GetInsertBlock();
+ llvm::BasicBlock *CleanupEndBB = CGF.createBasicBlock("ehcleanup.end");
+ llvm::Instruction *PadInst = CleanupBB->getFirstNonPHI();
+ auto *CPI = cast<llvm::CleanupPadInst>(PadInst);
+ CGBuilderTy(CGF, CleanupEndBB)
+ .CreateCleanupEndPad(CPI, CGF.getEHDispatchBlock(EnclosingScope));
+
+ // Push and pop the cleanupendpad around the call.
+ CGF.EHStack.pushPadEnd(CleanupEndBB);
CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
+ CGF.EHStack.popPadEnd();
+
+ // Insert the catchendpad block here.
+ CGF.CurFn->getBasicBlockList().insertAfter(CGF.Builder.GetInsertBlock(),
+ CleanupEndBB);
}
};
}
@@ -1779,7 +1802,8 @@ void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
// Push a cleanup for __finally blocks.
- EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
+ EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc,
+ EHStack.getInnermostEHScope());
return;
}
OpenPOWER on IntegriCloud