changeset 356:44daf304421c trunk

[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.
author ChristianK
date Mon, 14 Jul 2008 12:00:24 +0200
parents d8357f7004ca
children 82af71383b8a
files dmd/statement.h gen/asmstmt.cpp gen/llvmhelpers.cpp gen/llvmhelpers.h gen/statements.cpp
diffstat 5 files changed, 8 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/statement.h	Mon Jul 14 11:48:55 2008 +0200
+++ b/dmd/statement.h	Mon Jul 14 12:00:24 2008 +0200
@@ -910,6 +910,7 @@
 struct AsmBlockStatement : CompoundStatement
 {
     EnclosingHandler* enclosinghandler;
+    TryFinallyStatement* tf;
 
     AsmBlockStatement(Loc loc, Statements *s);
     Statements *flatten(Scope *sc);
--- a/gen/asmstmt.cpp	Mon Jul 14 11:48:55 2008 +0200
+++ b/gen/asmstmt.cpp	Mon Jul 14 12:00:24 2008 +0200
@@ -388,6 +388,7 @@
 :   CompoundStatement(loc, s)
 {
     enclosinghandler = NULL;
+    tf = NULL;
 }
 
 // rewrite argument indices to the block scope indices
@@ -648,7 +649,7 @@
             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::semantic(Scope *sc)
 {
     enclosinghandler = sc->tfOfTry;
+    tf = sc->tf;
 
     return CompoundStatement::semantic(sc);
 }
--- a/gen/llvmhelpers.cpp	Mon Jul 14 11:48:55 2008 +0200
+++ b/gen/llvmhelpers.cpp	Mon Jul 14 12:00:24 2008 +0200
@@ -175,7 +175,7 @@
 /*////////////////////////////////////////////////////////////////////////////////////////
 // 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 @@
 
     // 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
--- a/gen/llvmhelpers.h	Mon Jul 14 11:48:55 2008 +0200
+++ b/gen/llvmhelpers.h	Mon Jul 14 12:00:24 2008 +0200
@@ -17,7 +17,7 @@
 // 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
--- a/gen/statements.cpp	Mon Jul 14 11:48:55 2008 +0200
+++ b/gen/statements.cpp	Mon Jul 14 12:00:24 2008 +0200
@@ -1063,12 +1063,10 @@
     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);
 }