mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-18 13:53:14 +01:00
[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:
@@ -910,6 +910,7 @@ struct AsmStatement : Statement
|
||||
struct AsmBlockStatement : CompoundStatement
|
||||
{
|
||||
EnclosingHandler* enclosinghandler;
|
||||
TryFinallyStatement* tf;
|
||||
|
||||
AsmBlockStatement(Loc loc, Statements *s);
|
||||
Statements *flatten(Scope *sc);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user