From 0ef57dcfbe45df0b6185f560ae167e7d355c63aa Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sat, 28 Mar 2009 19:16:53 +0100 Subject: [PATCH] Reenable error for gotos into or out of finally blocks. --- gen/asmstmt.cpp | 2 +- gen/llvmhelpers.cpp | 9 ++++----- gen/llvmhelpers.h | 6 ++++-- gen/statements.cpp | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index 0df2c59d..1a264bf9 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -772,7 +772,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); + DtoGoto(loc, it->first, enclosingFinally); } p->scope() = IRScope(bb,oldend); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index b913404e..65e3a076 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -172,7 +172,7 @@ LabelStatement* DtoLabelStatement(Identifier* ident) /*//////////////////////////////////////////////////////////////////////////////////////// // GOTO HELPER ////////////////////////////////////////////////////////////////////////////////////////*/ -void DtoGoto(Loc loc, Identifier* target) +void DtoGoto(Loc loc, Identifier* target, TryFinallyStatement* sourceFinally) { assert(!gIR->scopereturned()); @@ -199,11 +199,10 @@ void DtoGoto(Loc loc, Identifier* target) // goto into finally blocks is forbidden by the spec // but should work fine - /* - if(lblstmt->tf != sourcetf) { - error(loc, "spec disallows goto into finally block"); + if(lblstmt->enclosingFinally != sourceFinally) { + error(loc, "spec disallows goto into or out of finally block"); fatal(); - }*/ + } llvm::BranchInst::Create(targetBB, gIR->scopebb()); } diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index b7631a86..99d2a014 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -45,8 +45,10 @@ void DtoAssert(Module* M, 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); + +/// emits goto to LabelStatement with the target identifier +/// the sourceFinally is only used for error checking +void DtoGoto(Loc loc, Identifier* target, TryFinallyStatement* sourceFinally); // Generates IR for enclosing handlers between the current state and // the scope created by the 'target' statement. diff --git a/gen/statements.cpp b/gen/statements.cpp index b9fc55e4..4954e61f 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -1288,7 +1288,7 @@ void GotoStatement::toIR(IRState* p) llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); - DtoGoto(loc, label->ident); + DtoGoto(loc, label->ident, enclosingFinally); p->scope() = IRScope(bb,oldend); }