mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-12 10:53:14 +01:00
Fix #308 by giving finally code emitted by EnclosingTryFinally a different landing pad.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -117,6 +117,8 @@ IrFunction::IrFunction(FuncDeclaration* fd)
|
||||
_arguments = NULL;
|
||||
_argptr = NULL;
|
||||
|
||||
landingPad = NULL;
|
||||
|
||||
nextUnique.push(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user