# HG changeset patch # User ChristianK # Date 1216029624 -7200 # Node ID 44daf304421c1bd58fe5e54733ee48872d00a555 # Parent d8357f7004cae08b65f61d51931618b846f6d372 [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. diff -r d8357f7004ca -r 44daf304421c dmd/statement.h --- 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); diff -r d8357f7004ca -r 44daf304421c gen/asmstmt.cpp --- 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); } diff -r d8357f7004ca -r 44daf304421c gen/llvmhelpers.cpp --- 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 diff -r d8357f7004ca -r 44daf304421c gen/llvmhelpers.h --- 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 diff -r d8357f7004ca -r 44daf304421c gen/statements.cpp --- 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); }