[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.

This commit is contained in:
Christian Kamm
2008-07-14 12:00:24 +02:00
parent c1fbcd9942
commit bcc4cfdea4
5 changed files with 8 additions and 7 deletions
+1
View File
@@ -910,6 +910,7 @@ struct AsmStatement : Statement
struct AsmBlockStatement : CompoundStatement struct AsmBlockStatement : CompoundStatement
{ {
EnclosingHandler* enclosinghandler; EnclosingHandler* enclosinghandler;
TryFinallyStatement* tf;
AsmBlockStatement(Loc loc, Statements *s); AsmBlockStatement(Loc loc, Statements *s);
Statements *flatten(Scope *sc); Statements *flatten(Scope *sc);
+3 -1
View File
@@ -388,6 +388,7 @@ AsmBlockStatement::AsmBlockStatement(Loc loc, Statements* s)
: CompoundStatement(loc, s) : CompoundStatement(loc, s)
{ {
enclosinghandler = NULL; enclosinghandler = NULL;
tf = NULL;
} }
// rewrite argument indices to the block scope indices // rewrite argument indices to the block scope indices
@@ -648,7 +649,7 @@ void AsmBlockStatement::toIR(IRState* p)
sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->second), casebb); sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->second), casebb);
p->scope() = IRScope(casebb,bb); p->scope() = IRScope(casebb,bb);
DtoGoto(&loc, it->first, enclosinghandler); DtoGoto(&loc, it->first, enclosinghandler, tf);
} }
p->scope() = IRScope(bb,oldend); p->scope() = IRScope(bb,oldend);
@@ -680,6 +681,7 @@ Statement *AsmBlockStatement::syntaxCopy()
Statement *AsmBlockStatement::semantic(Scope *sc) Statement *AsmBlockStatement::semantic(Scope *sc)
{ {
enclosinghandler = sc->tfOfTry; enclosinghandler = sc->tfOfTry;
tf = sc->tf;
return CompoundStatement::semantic(sc); return CompoundStatement::semantic(sc);
} }
+2 -2
View File
@@ -175,7 +175,7 @@ LabelStatement* DtoLabelStatement(Identifier* ident)
/*//////////////////////////////////////////////////////////////////////////////////////// /*////////////////////////////////////////////////////////////////////////////////////////
// GOTO HELPER // GOTO HELPER
////////////////////////////////////////////////////////////////////////////////////////*/ ////////////////////////////////////////////////////////////////////////////////////////*/
void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler) void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler, TryFinallyStatement* sourcetf)
{ {
assert(!gIR->scopereturned()); assert(!gIR->scopereturned());
@@ -204,7 +204,7 @@ void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler)
// goto into finally blocks is forbidden by the spec // goto into finally blocks is forbidden by the spec
// though it should not be problematic to implement // though it should not be problematic to implement
if(lblstmt->tf) if(lblstmt->tf != sourcetf)
error(*loc, "spec disallows goto into finally block"); error(*loc, "spec disallows goto into finally block");
// emit code for finallys between goto and label // emit code for finallys between goto and label
+1 -1
View File
@@ -17,7 +17,7 @@ void DtoAssert(Loc* loc, DValue* msg);
// return the LabelStatement from the current function with the given identifier or NULL if not found // return the LabelStatement from the current function with the given identifier or NULL if not found
LabelStatement* DtoLabelStatement(Identifier* ident); LabelStatement* DtoLabelStatement(Identifier* ident);
// emit goto // 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 // generates IR for finally blocks between the 'start' and 'end' statements
// will begin with the finally block belonging to 'start' and does not include // will begin with the finally block belonging to 'start' and does not include
+1 -3
View File
@@ -1063,12 +1063,10 @@ void GotoStatement::toIR(IRState* p)
if (global.params.symdebug) if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum); DtoDwarfStopPoint(loc.linnum);
assert(tf == NULL);
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); 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); p->scope() = IRScope(bb,oldend);
} }