mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-09-20 04:10:18 +02: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
|
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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user