diff options
author | Reid Kleckner <rnk@google.com> | 2015-09-10 22:11:13 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-09-10 22:11:13 +0000 |
commit | 2586aac9087a9864ebd6cdee4f1f747e86eceaad (patch) | |
tree | fb8e71992550760423f6c7e36f98e57b995f887f /clang/lib/CodeGen/CGException.cpp | |
parent | da6dcc5d926cb7481ff28b127c5e67da4501a99c (diff) | |
download | bcm5719-llvm-2586aac9087a9864ebd6cdee4f1f747e86eceaad.tar.gz bcm5719-llvm-2586aac9087a9864ebd6cdee4f1f747e86eceaad.zip |
[SEH] Use cleanupendpad so that WinEHPrepare gets the coloring right
Cleanupendpad is a lot like catchendpad, so we can reuse the same
EHScopeStack type.
llvm-svn: 247349
Diffstat (limited to 'clang/lib/CodeGen/CGException.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 52 |
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; } |