diff -r 349f85192e52 d/d-codegen.cc
--- a/d/d-codegen.cc	Wed Aug 11 18:45:39 2010 +0100
+++ b/d/d-codegen.cc	Sat Aug 14 09:55:02 2010 +0100
@@ -2924,7 +2924,8 @@
     clear_last_expr ();
     g.ofile->doLineNote(stmt->loc);
     expand_start_case( 1, t_cond, TREE_TYPE( t_cond ), "switch statement" );
-    beginFlow(stmt, NULL);
+    Flow * f = beginFlow(stmt, NULL);
+    f->switchScope = currentScope();
 }
 
 void
@@ -3069,7 +3070,7 @@
 {
     tree t_cond = convertForCondition(e_cond);
 
-    Flow * f = beginFlow(stmt/*, 0*/);
+    Flow * f = beginFlow(stmt);
     f->condition = t_cond;
 }
 
@@ -3101,7 +3102,7 @@
 
 void
 IRState::startLoop(Statement * stmt) {
-    Flow * f = beginFlow(stmt/*, Break|Continue*/);
+    Flow * f = beginFlow(stmt);
     f->continueLabel = label(stmt ? stmt->loc : 0); // should be end for 'do' loop
 }
 
@@ -3127,6 +3128,7 @@
 {
     Flow * f = beginFlow(stmt);
     f->condition = t_cond;
+    f->switchScope = currentScope();
 }
 
 void
diff -r 349f85192e52 d/d-glue.cc
--- a/d/d-glue.cc	Wed Aug 11 18:45:39 2010 +0100
+++ b/d/d-glue.cc	Sat Aug 14 09:55:02 2010 +0100
@@ -3762,6 +3762,7 @@
 void
 TryFinallyStatement::toIR(IRState * irs)
 {
+#if D_GCC_VER < 40
     // %% doc: this is not the same as a start_eh/end_eh_cleanup sequence
     tree t_body = body ? irs->makeStmtExpr(body) : d_void_zero_node;
     tree t_finl = finalbody ? irs->makeStmtExpr(finalbody) : d_void_zero_node;
@@ -3769,6 +3770,16 @@
     // TREE_SIDE_EFFECTS(tf) = 1; // probably not needed
     irs->doLineNote(loc);
     irs->doExp(tf);
+#else
+    irs->doLineNote(loc);
+    irs->startTry(this);
+    if (body)
+	body->toIR(irs);
+    irs->startFinally();
+    if (finalbody)
+	finalbody->toIR(irs);
+    irs->endFinally();
+#endif
 }
 
 void
@@ -3897,7 +3908,7 @@
 	g.ofile->rodc(critsec_decl, 1);
 
 #if D_GCC_VER < 40
-	expand_eh_region_start();	
+	expand_eh_region_start();
 	expand_expr_stmt_value(irs->libCall(LIBCALL_CRITICALENTER, 1, & critsec_ref), 0, 1);
 	if (body)
 	    body->toIR( irs );
@@ -3963,6 +3974,8 @@
 void
 DefaultStatement::toIR(IRState * irs)
 {
+    if(! irs->inSwitchScope() )
+	error("default cannot be in different try block level from switch");
     irs->doCase(NULL_TREE, cblock);
     if (statement)
 	statement->toIR( irs );
@@ -3973,6 +3986,9 @@
 {
     tree case_value;
 
+    if(! irs->inSwitchScope() )
+	error("case cannot be in different try block level from switch");
+
     if ( exp->type->isscalar() )
 	case_value = exp->toElem(irs);
     else
diff -r 349f85192e52 d/d-irstate.cc
--- a/d/d-irstate.cc	Wed Aug 11 18:45:39 2010 +0100
+++ b/d/d-irstate.cc	Sat Aug 14 09:55:02 2010 +0100
@@ -293,7 +293,7 @@
 #else
 
 IRBase::Flow *
-IRBase::beginFlow(Statement * stmt/*, int labels*/)
+IRBase::beginFlow(Statement * stmt)
 {
     Flow * flow = new Flow;
     
@@ -301,16 +301,6 @@
     flow->exitLabel = NULL_TREE;
     flow->condition = NULL_TREE;
     flow->trueBranch = NULL_TREE;
-    /*
-    if (labels & Break)
-	flow->exitLabel = error_mark_node; // don't create until needed
-    if (labels & Continue) {
-	flow->continueLabel = build_decl(LABEL_DECL, NULL, void_type_node);
-	DECL_CONTEXT( flow->continueLabel ) = getLocalContext();
-	//used,mode?
-    }
-    flow->exitLabel = NULL;
-    */
     
     loops.push(flow);
 
diff -r 349f85192e52 d/d-irstate.h
--- a/d/d-irstate.h	Wed Aug 11 18:45:39 2010 +0100
+++ b/d/d-irstate.h	Sat Aug 14 09:55:02 2010 +0100
@@ -83,6 +83,7 @@
     typedef struct
     {
 	Statement * statement;
+	unsigned * switchScope;
 	// expand_start_case doesn't return a nesting structure, so
 	// we have to generate our own label for 'break'
 	nesting * loop;
@@ -93,6 +94,7 @@
     typedef struct
     {
 	Statement * statement;
+	unsigned * switchScope;
 	tree exitLabel;
 	union {
 	    struct {
@@ -118,12 +120,20 @@
 #if D_GCC_VER < 40    
     Flow *    beginFlow(Statement * stmt, nesting * loop);
 #else
-    //typedef enum { Break = 0x1, Continue = 0x2 } FlowLabel;
-    Flow *    beginFlow(Statement * stmt/*, int labels*/);
+    Flow *    beginFlow(Statement * stmt);
 #endif
     void      endFlow();
     Flow *    currentFlow() { return (Flow *) loops.tos(); }
     void      doLabel(tree t_label);
+
+    bool inSwitchScope() {
+	unsigned * current = currentFlow()->switchScope;
+	for (unsigned i = 0; i < scopes.dim; i++) {
+	    if (current == scopes.data[i])
+		return 1;
+	}
+	return 0;
+    }
  
     // ** DECL_CONTEXT support
 
@@ -137,17 +147,18 @@
        a new scope. (And for now, until the emitLocalVar crash is
        solved, this also creates a default binding contour.)
        
-       "Binding countour": Same as GCC's definition, whatever that is.
+       "Binding contour": Same as GCC's definition, whatever that is.
        Each user-declared variable will have a binding contour that begins
        where the variable is declared and ends at it's containing scope.
     */
-    Array scopes; // of unsigned*
+    Array      scopes; // of unsigned*
     
-    void startScope();
-    void endScope();
+    void       startScope();
+    void       endScope();
+    unsigned * currentScope() { return (unsigned *) scopes.tos(); }
 
-    void startBindings();
-    void endBindings();
+    void       startBindings();
+    void       endBindings();
 
 
     // ** Volatile state
