# HG changeset patch # User Christian Kamm # Date 1243031019 -7200 # Node ID 3f5ea912149d5140cb7cb29a67da8b5a9ff609db # Parent e57859ca8f1e1df958a955447bc5f0a625899897 Fix #308 by giving finally code emitted by EnclosingTryFinally a different landing pad. diff -r e57859ca8f1e -r 3f5ea912149d gen/irstate.h --- a/gen/irstate.h Fri May 22 21:38:01 2009 +0200 +++ b/gen/irstate.h Sat May 23 00:23:39 2009 +0200 @@ -175,8 +175,8 @@ template 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(Callee); diff -r e57859ca8f1e -r 3f5ea912149d gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Fri May 22 21:38:01 2009 +0200 +++ b/gen/llvmhelpers.cpp Sat May 23 00:23:39 2009 +0200 @@ -255,7 +255,12 @@ 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; + } } //////////////////////////////////////////////////////////////////////////////////////// diff -r e57859ca8f1e -r 3f5ea912149d gen/llvmhelpers.h --- a/gen/llvmhelpers.h Fri May 22 21:38:01 2009 +0200 +++ b/gen/llvmhelpers.h Sat May 23 00:23:39 2009 +0200 @@ -15,8 +15,10 @@ 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 { diff -r e57859ca8f1e -r 3f5ea912149d gen/statements.cpp --- a/gen/statements.cpp Fri May 22 21:38:01 2009 +0200 +++ b/gen/statements.cpp Sat May 23 00:23:39 2009 +0200 @@ -592,8 +592,10 @@ 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 @@ 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 @@ 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 @@ 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); diff -r e57859ca8f1e -r 3f5ea912149d ir/irfunction.cpp --- a/ir/irfunction.cpp Fri May 22 21:38:01 2009 +0200 +++ b/ir/irfunction.cpp Sat May 23 00:23:39 2009 +0200 @@ -117,6 +117,8 @@ _arguments = NULL; _argptr = NULL; + landingPad = NULL; + nextUnique.push(0); } diff -r e57859ca8f1e -r 3f5ea912149d ir/irfunction.h --- a/ir/irfunction.h Fri May 22 21:38:01 2009 +0200 +++ b/ir/irfunction.h Sat May 23 00:23:39 2009 +0200 @@ -70,7 +70,8 @@ LabelToBBMap labelToBB; // landing pads for try statements - IRLandingPad landingPad; + IRLandingPad landingPadInfo; + llvm::BasicBlock* landingPad; // loop blocks typedef std::vector TargetScopeVec; diff -r e57859ca8f1e -r 3f5ea912149d ir/irlandingpad.cpp --- a/ir/irlandingpad.cpp Fri May 22 21:38:01 2009 +0200 +++ b/ir/irlandingpad.cpp Sat May 23 00:23:39 2009 +0200 @@ -24,7 +24,7 @@ #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 @@ 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); } }