summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-09-10 22:11:13 +0000
committerReid Kleckner <rnk@google.com>2015-09-10 22:11:13 +0000
commit2586aac9087a9864ebd6cdee4f1f747e86eceaad (patch)
treefb8e71992550760423f6c7e36f98e57b995f887f /clang/lib/CodeGen
parentda6dcc5d926cb7481ff28b127c5e67da4501a99c (diff)
downloadbcm5719-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')
-rw-r--r--clang/lib/CodeGen/CGCleanup.cpp8
-rw-r--r--clang/lib/CodeGen/CGCleanup.h22
-rw-r--r--clang/lib/CodeGen/CGException.cpp52
-rw-r--r--clang/lib/CodeGen/EHScopeStack.h4
4 files changed, 55 insertions, 31 deletions
diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index b5a64d0a28a..31c870ff6f6 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/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/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h
index d0569287ef0..5782343013c 100644
--- a/clang/lib/CodeGen/CGCleanup.h
+++ b/clang/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<EHCatchEndScope>(*begin());
+ EHPadEndScope &scope = cast<EHPadEndScope>(*begin());
InnermostEHScope = scope.getEnclosingEHScope();
- deallocate(EHCatchEndScope::getSize());
+ deallocate(EHPadEndScope::getSize());
}
inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const {
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;
}
diff --git a/clang/lib/CodeGen/EHScopeStack.h b/clang/lib/CodeGen/EHScopeStack.h
index 6d01095dfa7..6e0e2c7ad3b 100644
--- a/clang/lib/CodeGen/EHScopeStack.h
+++ b/clang/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
OpenPOWER on IntegriCloud