Mercurial > projects > ldc
changeset 356:44daf304421c trunk
[svn r377] The previous check was too strict, it completely disallowed gotos within finally blocks. This reenables them as long as they don't cross a finally boundary.
author | ChristianK |
---|---|
date | Mon, 14 Jul 2008 12:00:24 +0200 |
parents | d8357f7004ca |
children | 82af71383b8a |
files | dmd/statement.h gen/asmstmt.cpp gen/llvmhelpers.cpp gen/llvmhelpers.h gen/statements.cpp |
diffstat | 5 files changed, 8 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/statement.h Mon Jul 14 11:48:55 2008 +0200 +++ b/dmd/statement.h Mon Jul 14 12:00:24 2008 +0200 @@ -910,6 +910,7 @@ struct AsmBlockStatement : CompoundStatement { EnclosingHandler* enclosinghandler; + TryFinallyStatement* tf; AsmBlockStatement(Loc loc, Statements *s); Statements *flatten(Scope *sc);
--- a/gen/asmstmt.cpp Mon Jul 14 11:48:55 2008 +0200 +++ b/gen/asmstmt.cpp Mon Jul 14 12:00:24 2008 +0200 @@ -388,6 +388,7 @@ : CompoundStatement(loc, s) { enclosinghandler = NULL; + tf = NULL; } // rewrite argument indices to the block scope indices @@ -648,7 +649,7 @@ sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->second), casebb); p->scope() = IRScope(casebb,bb); - DtoGoto(&loc, it->first, enclosinghandler); + DtoGoto(&loc, it->first, enclosinghandler, tf); } p->scope() = IRScope(bb,oldend); @@ -680,6 +681,7 @@ Statement *AsmBlockStatement::semantic(Scope *sc) { enclosinghandler = sc->tfOfTry; + tf = sc->tf; return CompoundStatement::semantic(sc); }
--- a/gen/llvmhelpers.cpp Mon Jul 14 11:48:55 2008 +0200 +++ b/gen/llvmhelpers.cpp Mon Jul 14 12:00:24 2008 +0200 @@ -175,7 +175,7 @@ /*//////////////////////////////////////////////////////////////////////////////////////// // GOTO HELPER ////////////////////////////////////////////////////////////////////////////////////////*/ -void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler) +void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler, TryFinallyStatement* sourcetf) { assert(!gIR->scopereturned()); @@ -204,7 +204,7 @@ // goto into finally blocks is forbidden by the spec // though it should not be problematic to implement - if(lblstmt->tf) + if(lblstmt->tf != sourcetf) error(*loc, "spec disallows goto into finally block"); // emit code for finallys between goto and label
--- a/gen/llvmhelpers.h Mon Jul 14 11:48:55 2008 +0200 +++ b/gen/llvmhelpers.h Mon Jul 14 12:00:24 2008 +0200 @@ -17,7 +17,7 @@ // return the LabelStatement from the current function with the given identifier or NULL if not found LabelStatement* DtoLabelStatement(Identifier* ident); // emit goto -void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosingtryfinally); +void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosingtryfinally, TryFinallyStatement* sourcetf); // generates IR for finally blocks between the 'start' and 'end' statements // will begin with the finally block belonging to 'start' and does not include
--- a/gen/statements.cpp Mon Jul 14 11:48:55 2008 +0200 +++ b/gen/statements.cpp Mon Jul 14 12:00:24 2008 +0200 @@ -1063,12 +1063,10 @@ if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); - assert(tf == NULL); - llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); - DtoGoto(&loc, label->ident, enclosinghandler); + DtoGoto(&loc, label->ident, enclosinghandler, tf); p->scope() = IRScope(bb,oldend); }