forked from OSchip/llvm-project
Pull the terminate handler up so that we can use it for the catch
parameter setup code and set up the catch parameter setup code to protect that code with terminate. llvm-svn: 90340
This commit is contained in:
parent
8a96d3a355
commit
9732915bf9
|
@ -265,6 +265,10 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
true),
|
true),
|
||||||
"__gxx_personality_v0");
|
"__gxx_personality_v0");
|
||||||
Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
|
Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
|
||||||
|
llvm::Value *llvm_eh_exception =
|
||||||
|
CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
|
||||||
|
llvm::Value *llvm_eh_selector =
|
||||||
|
CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
|
||||||
|
|
||||||
llvm::BasicBlock *PrevLandingPad = getInvokeDest();
|
llvm::BasicBlock *PrevLandingPad = getInvokeDest();
|
||||||
llvm::BasicBlock *TryHandler = createBasicBlock("try.handler");
|
llvm::BasicBlock *TryHandler = createBasicBlock("try.handler");
|
||||||
|
@ -283,6 +287,28 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
// Jump to end if there is no exception
|
// Jump to end if there is no exception
|
||||||
EmitBranchThroughCleanup(FinallyEnd);
|
EmitBranchThroughCleanup(FinallyEnd);
|
||||||
|
|
||||||
|
// Set up terminate handler
|
||||||
|
llvm::BasicBlock *TerminateHandler = createBasicBlock("terminate.handler");
|
||||||
|
EmitBlock(TerminateHandler);
|
||||||
|
llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
|
||||||
|
// We are required to emit this call to satisfy LLVM, even
|
||||||
|
// though we don't use the result.
|
||||||
|
llvm::SmallVector<llvm::Value*, 8> Args;
|
||||||
|
Args.clear();
|
||||||
|
Args.push_back(Exc);
|
||||||
|
Args.push_back(Personality);
|
||||||
|
Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
|
||||||
|
0));
|
||||||
|
Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
|
||||||
|
llvm::CallInst *TerminateCall =
|
||||||
|
Builder.CreateCall(getTerminateFn(*this));
|
||||||
|
TerminateCall->setDoesNotReturn();
|
||||||
|
TerminateCall->setDoesNotThrow();
|
||||||
|
Builder.CreateUnreachable();
|
||||||
|
|
||||||
|
// Clear the insertion point to indicate we are in unreachable code.
|
||||||
|
Builder.ClearInsertionPoint();
|
||||||
|
|
||||||
// Emit the handlers
|
// Emit the handlers
|
||||||
EmitBlock(TryHandler);
|
EmitBlock(TryHandler);
|
||||||
|
|
||||||
|
@ -293,16 +319,13 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
|
PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
|
||||||
llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
|
llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
|
||||||
llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
|
llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
|
||||||
llvm::Value *llvm_eh_exception =
|
|
||||||
CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
|
|
||||||
llvm::Value *llvm_eh_selector =
|
|
||||||
CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
|
|
||||||
llvm::Value *llvm_eh_typeid_for =
|
llvm::Value *llvm_eh_typeid_for =
|
||||||
CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
|
CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
|
||||||
// Exception object
|
// Exception object
|
||||||
llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
|
Exc = Builder.CreateCall(llvm_eh_exception, "exc");
|
||||||
llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
|
llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
|
||||||
|
|
||||||
|
Args.clear();
|
||||||
SelectorArgs.push_back(Exc);
|
SelectorArgs.push_back(Exc);
|
||||||
SelectorArgs.push_back(Personality);
|
SelectorArgs.push_back(Personality);
|
||||||
|
|
||||||
|
@ -330,7 +353,6 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
llvm::Value *Selector
|
llvm::Value *Selector
|
||||||
= Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
|
= Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
|
||||||
SelectorArgs.end(), "selector");
|
SelectorArgs.end(), "selector");
|
||||||
llvm::BasicBlock *TerminateHandler = 0;
|
|
||||||
for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
|
for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
|
||||||
const CXXCatchStmt *C = S.getHandler(i);
|
const CXXCatchStmt *C = S.getHandler(i);
|
||||||
VarDecl *CatchParam = C->getExceptionDecl();
|
VarDecl *CatchParam = C->getExceptionDecl();
|
||||||
|
@ -362,6 +384,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
// Bind the catch parameter if it exists.
|
// Bind the catch parameter if it exists.
|
||||||
if (CatchParam) {
|
if (CatchParam) {
|
||||||
QualType CatchType = CatchParam->getType().getNonReferenceType();
|
QualType CatchType = CatchParam->getType().getNonReferenceType();
|
||||||
|
setInvokeDest(TerminateHandler);
|
||||||
if (!CatchType.getTypePtr()->isPointerType())
|
if (!CatchType.getTypePtr()->isPointerType())
|
||||||
CatchType = getContext().getPointerType(CatchType);
|
CatchType = getContext().getPointerType(CatchType);
|
||||||
ExcObject =
|
ExcObject =
|
||||||
|
@ -377,6 +400,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
CopyObject(*this, CatchParam->getType().getNonReferenceType(),
|
CopyObject(*this, CatchParam->getType().getNonReferenceType(),
|
||||||
ExcObject, GetAddrOfLocalVar(CatchParam));
|
ExcObject, GetAddrOfLocalVar(CatchParam));
|
||||||
#endif
|
#endif
|
||||||
|
setInvokeDest(MatchHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitStmt(CatchBody);
|
EmitStmt(CatchBody);
|
||||||
|
@ -387,7 +411,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
|
llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
|
||||||
// We are required to emit this call to satisfy LLVM, even
|
// We are required to emit this call to satisfy LLVM, even
|
||||||
// though we don't use the result.
|
// though we don't use the result.
|
||||||
llvm::SmallVector<llvm::Value*, 8> Args;
|
Args.clear();
|
||||||
Args.push_back(Exc);
|
Args.push_back(Exc);
|
||||||
Args.push_back(Personality);
|
Args.push_back(Personality);
|
||||||
Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
|
Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
|
||||||
|
@ -400,12 +424,6 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
|
|
||||||
EmitBlock(MatchEnd);
|
EmitBlock(MatchEnd);
|
||||||
|
|
||||||
// Set up terminate handler
|
|
||||||
bool GenerateTerminate = false;
|
|
||||||
if (!TerminateHandler) {
|
|
||||||
TerminateHandler = createBasicBlock("terminate.handler");
|
|
||||||
GenerateTerminate = true;
|
|
||||||
}
|
|
||||||
llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
|
llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
|
||||||
Builder.CreateInvoke(getEndCatchFn(*this),
|
Builder.CreateInvoke(getEndCatchFn(*this),
|
||||||
Cont, TerminateHandler,
|
Cont, TerminateHandler,
|
||||||
|
@ -421,28 +439,6 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
|
||||||
Builder.CreateStore(Exc, RethrowPtr);
|
Builder.CreateStore(Exc, RethrowPtr);
|
||||||
EmitBranchThroughCleanup(FinallyRethrow);
|
EmitBranchThroughCleanup(FinallyRethrow);
|
||||||
|
|
||||||
if (GenerateTerminate) {
|
|
||||||
GenerateTerminate = false;
|
|
||||||
EmitBlock(TerminateHandler);
|
|
||||||
Exc = Builder.CreateCall(llvm_eh_exception, "exc");
|
|
||||||
// We are required to emit this call to satisfy LLVM, even
|
|
||||||
// though we don't use the result.
|
|
||||||
Args.clear();
|
|
||||||
Args.push_back(Exc);
|
|
||||||
Args.push_back(Personality);
|
|
||||||
Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
|
|
||||||
0));
|
|
||||||
Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
|
|
||||||
llvm::CallInst *TerminateCall =
|
|
||||||
Builder.CreateCall(getTerminateFn(*this));
|
|
||||||
TerminateCall->setDoesNotReturn();
|
|
||||||
TerminateCall->setDoesNotThrow();
|
|
||||||
Builder.CreateUnreachable();
|
|
||||||
|
|
||||||
// Clear the insertion point to indicate we are in unreachable code.
|
|
||||||
Builder.ClearInsertionPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Next)
|
if (Next)
|
||||||
EmitBlock(Next);
|
EmitBlock(Next);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue