diff -rupdwN /home/chad/downloads/dlang/dmd.2.036/src/dmd/lexer.c ./src/dmd/lexer.c
--- /home/chad/downloads/dlang/dmd.2.036/src/dmd/lexer.c	2009-11-05 01:35:42.000000000 -0500
+++ ./src/dmd/lexer.c	2009-11-20 19:44:23.000000000 -0500
@@ -1122,6 +1122,13 @@ void Lexer::scan(Token *t)
 		    else
 			t->value = TOKule;	// !>
 		}
+#if DMDV2
+		else if (*p == ':')
+		{
+		    p++;
+		    t->value = TOKfallthrough; // !:
+		}
+#endif
 		else
 		    t->value = TOKnot;		// !
 		return;
@@ -3008,6 +3015,7 @@ void Lexer::initKeywords()
     Token::tochars[TOKrbracket]		= "]";
     Token::tochars[TOKsemicolon]	= ";";
     Token::tochars[TOKcolon]		= ":";
+    Token::tochars[TOKfallthrough]	= "!:";
     Token::tochars[TOKcomma]		= ",";
     Token::tochars[TOKdot]		= ".";
     Token::tochars[TOKxor]		= "^";
diff -rupdwN /home/chad/downloads/dlang/dmd.2.036/src/dmd/lexer.h ./src/dmd/lexer.h
--- /home/chad/downloads/dlang/dmd.2.036/src/dmd/lexer.h	2009-11-05 01:35:42.000000000 -0500
+++ ./src/dmd/lexer.h	2009-11-19 03:41:01.000000000 -0500
@@ -162,6 +162,7 @@ enum TOK
 	TOKfile,
 	TOKshared,
 	TOKat,
+	TOKfallthrough,
 #endif
 
 	TOKMAX
diff -rupdwN /home/chad/downloads/dlang/dmd.2.036/src/dmd/parse.c ./src/dmd/parse.c
--- /home/chad/downloads/dlang/dmd.2.036/src/dmd/parse.c	2009-11-05 01:35:42.000000000 -0500
+++ ./src/dmd/parse.c	2009-11-20 14:43:31.000000000 -0500
@@ -3712,7 +3712,25 @@ Statement *Parser::parseStatement(int fl
 		if (token.value != TOKcomma)
 		    break;
 	    }
+
+	    int fallThroughAllowed = TRUE; // D1 behavior.
+#if DMDV2
+	    int lastColon = token.value;
+	    if ( token.value == TOKcolon )
+	    {
+		fallThroughAllowed = FALSE;
+		nextToken();
+	    }
+	    else if ( token.value == TOKfallthrough )
+	    {
+		fallThroughAllowed = TRUE;
+		nextToken();
+	    }
+	    else
+		error(": or !: expected after case, not %s", token.toChars());
+#else
 	    check(TOKcolon);
+#endif
 
 #if DMDV2
 	    /* case exp: .. case last:
@@ -3724,6 +3742,10 @@ Statement *Parser::parseStatement(int fl
 		nextToken();
 		check(TOKcase);
 		last = parseAssignExp();
+		
+		if ( fallThroughAllowed )
+		    check(TOKfallthrough);
+		else
 		check(TOKcolon);
 	    }
 #endif
@@ -3742,16 +3764,21 @@ Statement *Parser::parseStatement(int fl
 #if DMDV2
 	    if (last)
 	    {
-		s = new CaseRangeStatement(loc, exp, last, s);
+		s = new CaseRangeStatement(loc, exp, last, s, fallThroughAllowed);
 	    }
 	    else
 #endif
 	    {
+		// case 0, 1, 6: break; -> case 0: { case 1: { case 6: {break;} } }
 		// Keep cases in order by building the case statements backwards
 		for (int i = cases.dim; i; i--)
 		{
 		    exp = (Expression *)cases.data[i - 1];
-		    s = new CaseStatement(loc, exp, s);
+		    s = new CaseStatement(loc, exp, s, fallThroughAllowed);
+		    
+		    // All of the cases that will follow will need to 
+		    //   fallthrough to reach the last one.
+		    fallThroughAllowed = TRUE;
 		}
 	    }
 	    break;
@@ -3762,7 +3789,24 @@ Statement *Parser::parseStatement(int fl
 	    Statements *statements;
 
 	    nextToken();
+	    
+	    int fallThroughAllowed = TRUE; // D1 behavior.
+#if DMDV2
+	    if ( token.value == TOKcolon )
+	    {
+		fallThroughAllowed = FALSE;
+		nextToken();
+	    }
+	    else if ( token.value == TOKfallthrough )
+	    {
+		fallThroughAllowed = TRUE;
+		nextToken();
+	    }
+	    else
+		error(": or !: expected after default, not %s", token.toChars());
+#else
 	    check(TOKcolon);
+#endif
 
 	    statements = new Statements();
 	    while (token.value != TOKcase &&
@@ -3774,7 +3818,7 @@ Statement *Parser::parseStatement(int fl
 	    }
 	    s = new CompoundStatement(loc, statements);
 	    s = new ScopeStatement(loc, s);
-	    s = new DefaultStatement(loc, s);
+	    s = new DefaultStatement(loc, s, fallThroughAllowed);
 	    break;
 	}
 
diff -rupdwN /home/chad/downloads/dlang/dmd.2.036/src/dmd/statement.c ./src/dmd/statement.c
--- /home/chad/downloads/dlang/dmd.2.036/src/dmd/statement.c	2009-11-05 01:35:42.000000000 -0500
+++ ./src/dmd/statement.c	2009-11-20 18:01:08.000000000 -0500
@@ -154,6 +154,12 @@ int Statement::isEmpty()
     return FALSE;
 }
 
+// See the declaration in statement.h for the description.
+int Statement::isUnconditionalBranch()
+{
+    return FALSE;
+}
+
 /****************************************
  * If this statement has code that needs to run in a finally clause
  * at the end of the current scope, return that code in the form of
@@ -267,7 +273,6 @@ int ExpStatement::isEmpty()
     return exp == NULL;
 }
 
-
 /******************************** CompileStatement ***************************/
 
 CompileStatement::CompileStatement(Loc loc, Expression *exp)
@@ -1906,14 +1911,14 @@ Lagain:
 
 		// default: break; takes care of cases 0 and 1
 		s = new BreakStatement(0, NULL);
-		s = new DefaultStatement(0, s);
+		s = new DefaultStatement(0, s, TRUE);
 		a->push(s);
 
 		// cases 2...
 		for (int i = 0; i < cases.dim; i++)
 		{
 		    s = (Statement *)cases.data[i];
-		    s = new CaseStatement(0, new IntegerExp(i + 2), s);
+		    s = new CaseStatement(0, new IntegerExp(i + 2), s, TRUE);
 		    a->push(s);
 		}
 
@@ -2751,7 +2756,7 @@ Statement *SwitchStatement::semantic(Sco
 	a->reserve(4);
 	a->push(body);
 	a->push(new BreakStatement(loc, NULL));
-	sc->sw->sdefault = new DefaultStatement(loc, s);
+	sc->sw->sdefault = new DefaultStatement(loc, s, TRUE);
 	a->push(sc->sw->sdefault);
 	cs = new CompoundStatement(loc, a);
 	body = cs;
@@ -2845,21 +2850,66 @@ void SwitchStatement::toCBuffer(OutBuffe
 
 /******************************** CaseStatement ***************************/
 
-CaseStatement::CaseStatement(Loc loc, Expression *exp, Statement *s)
+CaseStatement::CaseStatement(Loc loc, Expression *exp, Statement *s, int fallThroughAllowed)
     : Statement(loc)
 {
     this->exp = exp;
     this->statement = s;
+    this->fallThroughAllowed = fallThroughAllowed;
     index = 0;
     cblock = NULL;
 }
 
 Statement *CaseStatement::syntaxCopy()
 {
-    CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy());
+    CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy(), fallThroughAllowed);
     return s;
 }
 
+void checkFallThrough( Loc loc, Statement *body )
+{
+    //printf("checkFallThrough(...)\n");
+    //printf("\n=================\n");
+    //printf("checkForEndingUnconditionalBranch: %s", body->toChars());
+    
+    // Unravel any scope statements that typically wrap the compound statements
+    //   that are found in CaseStatements and the like.
+    if ( body )
+    {
+	ScopeStatement *tmp = body->isScopeStatement();
+	if ( tmp )
+	    body = tmp->statement;
+    }
+    
+    // Turn it into a CompoundStatement if it exists and is one.
+    CompoundStatement *block = NULL;
+    if ( body )
+	block = body->isCompoundStatement();
+    
+    // Now actually check for the unconditional branch.
+    if ( block )
+    {
+	Statements *array = block->statements;
+	Statement *lastStatement = NULL;
+	if ( 1 <= array->dim )
+	    lastStatement = (Statement*)array->data[array->dim - 1];
+	
+	if ( !lastStatement || !lastStatement->isUnconditionalBranch() )
+	{
+	    error(loc,"The last statement in a case or default statement "
+		"must be one of these unconditional branches: break, return, "
+		"continue, goto, goto case, goto default, or throw.  "
+		"For fall through, use 'case foo!:' or 'default!:'");
+	}
+    }
+    else
+    {
+	printf("statement.c %d: %s: This is unexpected.  ", __LINE__, loc.toChars());
+	printf("A case or default statement just managed to avoid being ");
+	printf("checked for an explicit unconditional branch.\n");
+    }
+}
+
 Statement *CaseStatement::semantic(Scope *sc)
 {   SwitchStatement *sw = sc->sw;
 
@@ -2870,6 +2920,9 @@ Statement *CaseStatement::semantic(Scope
 	exp = exp->implicitCastTo(sc, sw->condition->type);
 	exp = exp->optimize(WANTvalue | WANTinterpret);
 
+	if ( !this->fallThroughAllowed )
+	    checkFallThrough(loc,statement);
+
 	/* This is where variables are allowed as case expressions.
 	 */
 	if (exp->op == TOKvar)
@@ -2966,18 +3019,20 @@ void CaseStatement::toCBuffer(OutBuffer 
 #if DMDV2
 
 CaseRangeStatement::CaseRangeStatement(Loc loc, Expression *first,
-	Expression *last, Statement *s)
+	Expression *last, Statement *s, int fallThroughAllowed)
     : Statement(loc)
 {
     this->first = first;
     this->last = last;
     this->statement = s;
+    this->fallThroughAllowed = fallThroughAllowed;
 }
 
 Statement *CaseRangeStatement::syntaxCopy()
 {
     CaseRangeStatement *s = new CaseRangeStatement(loc,
-	first->syntaxCopy(), last->syntaxCopy(), statement->syntaxCopy());
+	first->syntaxCopy(), last->syntaxCopy(), statement->syntaxCopy(), 
+	fallThroughAllowed);
     return s;
 }
 
@@ -3019,8 +3074,13 @@ Statement *CaseRangeStatement::semantic(
 	Statement *s = statement;
 	if (i != lval)
 	    s = new ExpStatement(loc, NULL);
+	
+	int fallThrough = TRUE;
+	if ( i == lval )
+	    fallThrough = this->fallThroughAllowed;
+	
 	Expression *e = new IntegerExp(loc, i, first->type);
-	Statement *cs = new CaseStatement(loc, e, s);
+	CaseStatement *cs = new CaseStatement(loc, e, s, fallThrough);
 	statements->push(cs);
     }
     Statement *s = new CompoundStatement(loc, statements);
@@ -3042,10 +3102,11 @@ void CaseRangeStatement::toCBuffer(OutBu
 
 /******************************** DefaultStatement ***************************/
 
-DefaultStatement::DefaultStatement(Loc loc, Statement *s)
+DefaultStatement::DefaultStatement(Loc loc, Statement *s, int fallThroughAllowed)
     : Statement(loc)
 {
     this->statement = s;
+    this->fallThroughAllowed = fallThroughAllowed;
 #if IN_GCC
 +    cblock = NULL;
 #endif
@@ -3053,7 +3114,7 @@ DefaultStatement::DefaultStatement(Loc l
 
 Statement *DefaultStatement::syntaxCopy()
 {
-    DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy());
+    DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy(), fallThroughAllowed);
     return s;
 }
 
@@ -3062,6 +3123,9 @@ Statement *DefaultStatement::semantic(Sc
     //printf("DefaultStatement::semantic()\n");
     if (sc->sw)
     {
+	if ( !this->fallThroughAllowed )
+	    checkFallThrough(loc,statement);
+	
 	if (sc->sw->sdefault)
 	{
 	    error("switch statement already has a default");
@@ -3135,6 +3199,11 @@ void GotoDefaultStatement::toCBuffer(Out
     buf->writestring("goto default;\n");
 }
 
+int GotoDefaultStatement::isUnconditionalBranch()
+{
+    return TRUE;
+}
+
 /******************************** GotoCaseStatement ***************************/
 
 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
@@ -3187,6 +3256,11 @@ void GotoCaseStatement::toCBuffer(OutBuf
     buf->writenl();
 }
 
+int GotoCaseStatement::isUnconditionalBranch()
+{
+    return TRUE;
+}
+
 /******************************** SwitchErrorStatement ***************************/
 
 SwitchErrorStatement::SwitchErrorStatement(Loc loc)
@@ -3510,6 +3584,11 @@ void ReturnStatement::toCBuffer(OutBuffe
     buf->writenl();
 }
 
+int ReturnStatement::isUnconditionalBranch()
+{
+    return TRUE;
+}
+
 /******************************** BreakStatement ***************************/
 
 BreakStatement::BreakStatement(Loc loc, Identifier *ident)
@@ -3603,6 +3682,11 @@ void BreakStatement::toCBuffer(OutBuffer
     buf->writenl();
 }
 
+int BreakStatement::isUnconditionalBranch()
+{
+    return TRUE;
+}
+
 /******************************** ContinueStatement ***************************/
 
 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
@@ -3703,6 +3787,11 @@ void ContinueStatement::toCBuffer(OutBuf
     buf->writenl();
 }
 
+int ContinueStatement::isUnconditionalBranch()
+{
+    return TRUE;
+}
+
 /******************************** SynchronizedStatement ***************************/
 
 SynchronizedStatement::SynchronizedStatement(Loc loc, Expression *exp, Statement *body)
@@ -4335,6 +4424,11 @@ void ThrowStatement::toCBuffer(OutBuffer
     buf->writenl();
 }
 
+int ThrowStatement::isUnconditionalBranch()
+{
+    return TRUE;
+}
+
 /******************************** VolatileStatement **************************/
 
 VolatileStatement::VolatileStatement(Loc loc, Statement *statement)
@@ -4451,6 +4545,11 @@ void GotoStatement::toCBuffer(OutBuffer 
     buf->writenl();
 }
 
+int GotoStatement::isUnconditionalBranch()
+{
+    return TRUE;
+}
+
 /******************************** LabelStatement ***************************/
 
 LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
@@ -4541,6 +4640,11 @@ void LabelStatement::toCBuffer(OutBuffer
         statement->toCBuffer(buf, hgs);
 }
 
+int LabelStatement::isUnconditionalBranch()
+{
+    return statement->isUnconditionalBranch();
+}
+
 
 /******************************** LabelDsymbol ***************************/
 
diff -rupdwN /home/chad/downloads/dlang/dmd.2.036/src/dmd/statement.h ./src/dmd/statement.h
--- /home/chad/downloads/dlang/dmd.2.036/src/dmd/statement.h	2009-11-05 01:35:42.000000000 -0500
+++ ./src/dmd/statement.h	2009-11-20 17:21:35.000000000 -0500
@@ -113,6 +113,10 @@ struct Statement : Object
     virtual Expression *doInline(InlineDoState *ids);
     virtual Statement *inlineScan(InlineScanState *iss);
 
+    // Checks to see if the statement is one of the following:
+    //   return, goto, goto case, goto default, break, throw, continue
+    virtual int isUnconditionalBranch();
+
     // Back end
     virtual void toIR(IRState *irs);
 
@@ -483,11 +487,12 @@ struct CaseStatement : Statement
 {
     Expression *exp;
     Statement *statement;
+    int fallThroughAllowed; // TRUE or FALSE.
 
     int index;		// which case it is (since we sort this)
     block *cblock;	// back end: label for the block
 
-    CaseStatement(Loc loc, Expression *exp, Statement *s);
+    CaseStatement(Loc loc, Expression *exp, Statement *s, int fallThroughAllowed);
     Statement *syntaxCopy();
     Statement *semantic(Scope *sc);
     int compare(Object *obj);
@@ -509,8 +514,9 @@ struct CaseRangeStatement : Statement
     Expression *first;
     Expression *last;
     Statement *statement;
+    int fallThroughAllowed; // TRUE or FALSE.
 
-    CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s);
+    CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s, int fallThroughAllowed);
     Statement *syntaxCopy();
     Statement *semantic(Scope *sc);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -521,11 +527,12 @@ struct CaseRangeStatement : Statement
 struct DefaultStatement : Statement
 {
     Statement *statement;
+    int fallThroughAllowed; // TRUE or FALSE.
 #if IN_GCC
     block *cblock;	// back end: label for the block
 #endif
 
-    DefaultStatement(Loc loc, Statement *s);
+    DefaultStatement(Loc loc, Statement *s, int fallThroughAllowed);
     Statement *syntaxCopy();
     Statement *semantic(Scope *sc);
     int usesEH();
@@ -549,6 +556,7 @@ struct GotoDefaultStatement : Statement
     Expression *interpret(InterState *istate);
     int blockExit();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    int isUnconditionalBranch();
 
     void toIR(IRState *irs);
 };
@@ -564,6 +572,7 @@ struct GotoCaseStatement : Statement
     Expression *interpret(InterState *istate);
     int blockExit();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    int isUnconditionalBranch();
 
     void toIR(IRState *irs);
 };
@@ -587,6 +596,7 @@ struct ReturnStatement : Statement
     Statement *semantic(Scope *sc);
     int blockExit();
     Expression *interpret(InterState *istate);
+    int isUnconditionalBranch();
 
     int inlineCost(InlineCostState *ics);
     Expression *doInline(InlineDoState *ids);
@@ -607,6 +617,7 @@ struct BreakStatement : Statement
     Expression *interpret(InterState *istate);
     int blockExit();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    int isUnconditionalBranch();
 
     void toIR(IRState *irs);
 };
@@ -621,6 +632,7 @@ struct ContinueStatement : Statement
     Expression *interpret(InterState *istate);
     int blockExit();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    int isUnconditionalBranch();
 
     void toIR(IRState *irs);
 };
@@ -743,6 +755,7 @@ struct ThrowStatement : Statement
     Statement *semantic(Scope *sc);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     int blockExit();
+    int isUnconditionalBranch();
 
     Statement *inlineScan(InlineScanState *iss);
 
@@ -776,6 +789,7 @@ struct GotoStatement : Statement
     Statement *semantic(Scope *sc);
     int blockExit();
     Expression *interpret(InterState *istate);
+    int isUnconditionalBranch();
 
     void toIR(IRState *irs);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -789,6 +803,7 @@ struct LabelStatement : Statement
     TryFinallyStatement *tf;
     block *lblock;		// back end
     int isReturnLabel;
+    int isUnconditionalBranch();
 
     LabelStatement(Loc loc, Identifier *ident, Statement *statement);
     Statement *syntaxCopy();
