[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

View File

@@ -910,6 +910,7 @@ struct AsmStatement : Statement
struct AsmBlockStatement : CompoundStatement
{
EnclosingHandler* enclosinghandler;
TryFinallyStatement* tf;
AsmBlockStatement(Loc loc, Statements *s);
Statements *flatten(Scope *sc);

View File

@@ -388,6 +388,7 @@ AsmBlockStatement::AsmBlockStatement(Loc loc, Statements* s)
: CompoundStatement(loc, s)
{
enclosinghandler = NULL;
tf = NULL;
}
// 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);
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::syntaxCopy()
Statement *AsmBlockStatement::semantic(Scope *sc)
{
enclosinghandler = sc->tfOfTry;
tf = sc->tf;
return CompoundStatement::semantic(sc);
}

View File

@@ -175,7 +175,7 @@ LabelStatement* DtoLabelStatement(Identifier* ident)
/*////////////////////////////////////////////////////////////////////////////////////////
// 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 @@ void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler)
// 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

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

View File

@@ -1063,12 +1063,10 @@ void GotoStatement::toIR(IRState* p)
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);
}