changeset 1159:c6d6a68bb5db

Add back some enclosing scope-exit information to the frontend to produce proper error messages inside switch statements.
author Christian Kamm <kamm incasoftware de>
date Sat, 28 Mar 2009 14:39:16 +0100
parents 08c1c3bfea5a
children 7d28dcbff23e
files dmd/statement.c dmd/statement.h
diffstat 2 files changed, 34 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/statement.c	Sat Mar 28 14:26:23 2009 +0100
+++ b/dmd/statement.c	Sat Mar 28 14:39:16 2009 +0100
@@ -2238,6 +2238,8 @@
     sdefault = NULL;
     cases = NULL;
     hasNoDefault = 0;
+    // LDC
+    enclosingScopeExit = NULL;
 }
 
 Statement *SwitchStatement::syntaxCopy()
@@ -2252,6 +2254,9 @@
     //printf("SwitchStatement::semantic(%p)\n", this);
     assert(!cases);		// ensure semantic() is only run once
 
+    // LDC
+    enclosingScopeExit = sc->enclosingScopeExit;
+
     condition = condition->semantic(sc);
     condition = resolveProperties(sc, condition);
     if (condition->type->isString())
@@ -2404,6 +2409,8 @@
     cblock = NULL;
     bodyBB = NULL;
     llvmIdx = NULL;
+    // LDC
+    enclosingScopeExit = NULL;
 }
 
 Statement *CaseStatement::syntaxCopy()
@@ -2416,6 +2423,14 @@
 {   SwitchStatement *sw = sc->sw;
 
     //printf("CaseStatement::semantic() %s\n", toChars());
+    
+    // LDC
+    enclosingScopeExit = sc->enclosingScopeExit;
+    if (enclosingScopeExit != sw->enclosingScopeExit)
+    {
+	error("case must be inside the same try, synchronized or volatile level as switch");
+    }
+
     exp = exp->semantic(sc);
     if (sw)
     {
@@ -2500,6 +2515,8 @@
 +    cblock = NULL;
 #endif
     bodyBB = NULL;
+    // LDC
+    enclosingScopeExit = NULL;
 }
 
 Statement *DefaultStatement::syntaxCopy()
@@ -2511,6 +2528,7 @@
 Statement *DefaultStatement::semantic(Scope *sc)
 {
     //printf("DefaultStatement::semantic()\n");
+
     if (sc->sw)
     {
 	if (sc->sw->sdefault)
@@ -2518,6 +2536,13 @@
 	    error("switch statement already has a default");
 	}
 	sc->sw->sdefault = this;
+
+	// LDC
+	enclosingScopeExit = sc->enclosingScopeExit;
+	if (enclosingScopeExit != sc->sw->enclosingScopeExit)
+	{
+	    error("default must be inside the same try, synchronized or volatile level as switch");
+	}
     }
     else
 	error("default not in switch statement");
--- a/dmd/statement.h	Sat Mar 28 14:26:23 2009 +0100
+++ b/dmd/statement.h	Sat Mar 28 14:39:16 2009 +0100
@@ -469,6 +469,9 @@
     Array gotoCases;		// array of unresolved GotoCaseStatement's
     Array *cases;		// array of CaseStatement's
     int hasNoDefault;		// !=0 if no default statement
+    
+    // LDC
+    Statement *enclosingScopeExit;
 
     SwitchStatement(Loc loc, Expression *c, Statement *b);
     Statement *syntaxCopy();
@@ -491,6 +494,9 @@
     int index;		// which case it is (since we sort this)
     block *cblock;	// back end: label for the block
 
+    // LDC
+    Statement *enclosingScopeExit;
+
     CaseStatement(Loc loc, Expression *exp, Statement *s);
     Statement *syntaxCopy();
     Statement *semantic(Scope *sc);
@@ -519,6 +525,9 @@
     block *cblock;	// back end: label for the block
 #endif
 
+    // LDC
+    Statement *enclosingScopeExit;
+
     DefaultStatement(Loc loc, Statement *s);
     Statement *syntaxCopy();
     Statement *semantic(Scope *sc);