From 5e1234dd846f391c84f48e638f7685d5e79e6399 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 10 Sep 2015 22:11:13 +0000 Subject: [PATCH] [SEH] Use cleanupendpad so that WinEHPrepare gets the coloring right Cleanupendpad is a lot like catchendpad, so we can reuse the same EHScopeStack type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@247349 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCleanup.cpp | 8 ++--- lib/CodeGen/CGCleanup.h | 22 ++++++------- lib/CodeGen/CGException.cpp | 52 ++++++++++++++++++++++--------- lib/CodeGen/EHScopeStack.h | 4 +-- test/CodeGen/exceptions-seh-new.c | 6 +++- 5 files changed, 60 insertions(+), 32 deletions(-) diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index b5a64d0a28..31c870ff6f 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -262,10 +262,10 @@ void EHScopeStack::pushTerminate() { InnermostEHScope = stable_begin(); } -void EHScopeStack::pushCatchEnd(llvm::BasicBlock *CatchEndBlockBB) { - char *Buffer = allocate(EHCatchEndScope::getSize()); - auto *CES = new (Buffer) EHCatchEndScope(InnermostEHScope); - CES->setCachedEHDispatchBlock(CatchEndBlockBB); +void EHScopeStack::pushPadEnd(llvm::BasicBlock *PadEndBB) { + char *Buffer = allocate(EHPadEndScope::getSize()); + auto *CES = new (Buffer) EHPadEndScope(InnermostEHScope); + CES->setCachedEHDispatchBlock(PadEndBB); InnermostEHScope = stable_begin(); } diff --git a/lib/CodeGen/CGCleanup.h b/lib/CodeGen/CGCleanup.h index d0569287ef..5782343013 100644 --- a/lib/CodeGen/CGCleanup.h +++ b/lib/CodeGen/CGCleanup.h @@ -101,7 +101,7 @@ protected: }; public: - enum Kind { Cleanup, Catch, Terminate, Filter, CatchEnd }; + enum Kind { Cleanup, Catch, Terminate, Filter, PadEnd }; EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope) : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr), @@ -474,14 +474,14 @@ public: } }; -class EHCatchEndScope : public EHScope { +class EHPadEndScope : public EHScope { public: - EHCatchEndScope(EHScopeStack::stable_iterator enclosingEHScope) - : EHScope(CatchEnd, enclosingEHScope) {} - static size_t getSize() { return sizeof(EHCatchEndScope); } + EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope) + : EHScope(PadEnd, enclosingEHScope) {} + static size_t getSize() { return sizeof(EHPadEndScope); } static bool classof(const EHScope *scope) { - return scope->getKind() == CatchEnd; + return scope->getKind() == PadEnd; } }; @@ -523,8 +523,8 @@ public: Size = EHTerminateScope::getSize(); break; - case EHScope::CatchEnd: - Size = EHCatchEndScope::getSize(); + case EHScope::PadEnd: + Size = EHPadEndScope::getSize(); break; } Ptr += llvm::RoundUpToAlignment(Size, ScopeStackAlignment); @@ -574,12 +574,12 @@ inline void EHScopeStack::popTerminate() { deallocate(EHTerminateScope::getSize()); } -inline void EHScopeStack::popCatchEnd() { +inline void EHScopeStack::popPadEnd() { assert(!empty() && "popping exception stack when not empty"); - EHCatchEndScope &scope = cast(*begin()); + EHPadEndScope &scope = cast(*begin()); InnermostEHScope = scope.getEnclosingEHScope(); - deallocate(EHCatchEndScope::getSize()); + deallocate(EHPadEndScope::getSize()); } inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const { diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 1a20403e84..255cb841c8 100644 --- a/lib/CodeGen/CGException.cpp +++ b/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(*I); @@ -1028,7 +1028,7 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { isa(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(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(NormalAndEHCleanup, FinallyFunc); + EHStack.pushCleanup(NormalAndEHCleanup, FinallyFunc, + EHStack.getInnermostEHScope()); return; } diff --git a/lib/CodeGen/EHScopeStack.h b/lib/CodeGen/EHScopeStack.h index 6d01095dfa..6e0e2c7ad3 100644 --- a/lib/CodeGen/EHScopeStack.h +++ b/lib/CodeGen/EHScopeStack.h @@ -334,9 +334,9 @@ public: /// Pops a terminate handler off the stack. void popTerminate(); - void pushCatchEnd(llvm::BasicBlock *CatchEndBlockBB); + void pushPadEnd(llvm::BasicBlock *PadEndBB); - void popCatchEnd(); + void popPadEnd(); // Returns true iff the current scope is either empty or contains only // lifetime markers, i.e. no real cleanup code diff --git a/test/CodeGen/exceptions-seh-new.c b/test/CodeGen/exceptions-seh-new.c index a1f04601a9..aa056b9587 100644 --- a/test/CodeGen/exceptions-seh-new.c +++ b/test/CodeGen/exceptions-seh-new.c @@ -182,8 +182,12 @@ int basic_finally(int g) { // CHECK: [[cleanuppad]] // CHECK: %[[padtoken:[^ ]*]] = cleanuppad [] // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress() -// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) +// CHECK: invoke void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) +// CHECK: to label %[[cleanupcont:[^ ]*]] unwind label %[[cleanupend:[^ ]*]] +// CHECK: [[cleanupcont]] // CHECK: cleanupret %[[padtoken]] unwind to caller +// CHECK: [[cleanupend]] +// CHECK: cleanupendpad %[[padtoken]] unwind to caller // CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer) // CHECK: call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0) -- 2.40.0