Fix #308 by giving finally code emitted by EnclosingTryFinally a different landing pad.

This commit is contained in:
Christian Kamm
2009-05-23 00:23:39 +02:00
parent adfc5b3ee9
commit 5b799deeb4
7 changed files with 29 additions and 15 deletions

View File

@@ -175,8 +175,8 @@ struct IRState
template <typename InputIterator>
llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name)
{
llvm::BasicBlock* pad;
if(pad = func()->landingPad.get())
llvm::BasicBlock* pad = func()->landingPad;
if(pad)
{
// intrinsics don't support invoking and 'nounwind' functions don't need it.
LLFunction* funcval = llvm::dyn_cast<LLFunction>(Callee);

View File

@@ -255,7 +255,12 @@ void EnclosingVolatile::emitCode(IRState * p)
void EnclosingTryFinally::emitCode(IRState * p)
{
if (tf->finalbody)
{
llvm::BasicBlock* oldpad = p->func()->landingPad;
p->func()->landingPad = landingPad;
tf->finalbody->toIR(p);
p->func()->landingPad = oldpad;
}
}
////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -15,8 +15,10 @@ struct EnclosingHandler
struct EnclosingTryFinally : EnclosingHandler
{
TryFinallyStatement* tf;
llvm::BasicBlock* landingPad;
void emitCode(IRState* p);
EnclosingTryFinally(TryFinallyStatement* _tf) : tf(_tf) {}
EnclosingTryFinally(TryFinallyStatement* _tf, llvm::BasicBlock* _pad)
: tf(_tf), landingPad(_pad) {}
};
struct EnclosingVolatile : EnclosingHandler
{

View File

@@ -592,8 +592,10 @@ void TryFinallyStatement::toIR(IRState* p)
p->scope() = IRScope(landingpadbb, endbb);
assert(finalbody);
gIR->func()->landingPad.addFinally(finalbody);
gIR->func()->landingPad.push(landingpadbb);
gIR->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this,gIR->func()->landingPad),NULL,NULL));
gIR->func()->landingPadInfo.addFinally(finalbody);
gIR->func()->landingPadInfo.push(landingpadbb);
gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
//
// do the try block
@@ -601,15 +603,15 @@ void TryFinallyStatement::toIR(IRState* p)
p->scope() = IRScope(trybb,finallybb);
assert(body);
p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this),NULL,NULL));
body->toIR(p);
p->func()->targetScopes.pop_back();
// terminate try BB
if (!p->scopereturned())
llvm::BranchInst::Create(finallybb, p->scopebb());
gIR->func()->landingPad.pop();
gIR->func()->landingPadInfo.pop();
gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
gIR->func()->targetScopes.pop_back();
//
// do finally block
@@ -658,10 +660,11 @@ void TryCatchStatement::toIR(IRState* p)
for (int i = 0; i < catches->dim; i++)
{
Catch *c = (Catch *)catches->data[i];
gIR->func()->landingPad.addCatch(c, endbb);
gIR->func()->landingPadInfo.addCatch(c, endbb);
}
gIR->func()->landingPad.push(landingpadbb);
gIR->func()->landingPadInfo.push(landingpadbb);
gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
//
// do the try block
@@ -674,7 +677,8 @@ void TryCatchStatement::toIR(IRState* p)
if (!gIR->scopereturned())
llvm::BranchInst::Create(endbb, p->scopebb());
gIR->func()->landingPad.pop();
gIR->func()->landingPadInfo.pop();
gIR->func()->landingPad = gIR->func()->landingPadInfo.get();
// rewrite the scope
p->scope() = IRScope(endbb,oldend);

View File

@@ -117,6 +117,8 @@ IrFunction::IrFunction(FuncDeclaration* fd)
_arguments = NULL;
_argptr = NULL;
landingPad = NULL;
nextUnique.push(0);
}

View File

@@ -70,7 +70,8 @@ struct IrFunction : IrBase
LabelToBBMap labelToBB;
// landing pads for try statements
IRLandingPad landingPad;
IRLandingPad landingPadInfo;
llvm::BasicBlock* landingPad;
// loop blocks
typedef std::vector<IRTargetScope> TargetScopeVec;

View File

@@ -24,7 +24,7 @@ IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end)
#endif
assert(!catchstmt->var->ir.irLocal);
catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage();
LLValue* catch_var = gIR->func()->landingPadInfo.getExceptionStorage();
catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
}
@@ -32,8 +32,8 @@ IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end)
DtoDeclarationExp(catchstmt->var);
// the exception will only be stored in catch_var. copy it over if necessary
if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPad.getExceptionStorage()) {
LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPad.getExceptionStorage()), DtoType(catchstmt->var->type));
if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPadInfo.getExceptionStorage()) {
LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPadInfo.getExceptionStorage()), DtoType(catchstmt->var->type));
DtoStore(exc, catchstmt->var->ir.irLocal->value);
}
}