diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 20618d8bb..abf8e183d 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -741,16 +741,28 @@ int StatementBlock (struct SwitchCtrl* Switch) if (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) { LineInfo* LI1 = UseLineInfo (GetDiagnosticLI ()); int StmtFlags1 = AnyStatement (0, Switch); - int UnreachableWarning = 0; + int Unreachable = 0; /* True if code is unreachable */ + int UnreachableWarning = 0; /* True if warning was output */ while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) { LineInfo* LI2 = UseLineInfo (GetDiagnosticLI ()); int StmtFlags2 = AnyStatement (0, Switch); if (!UnreachableWarning) { - /* Check if the code is unreachable because of a preceeding - ** jump and if the code doesn't have a jump label. + /* If this statement is not already unreachable, check if the + ** previous statement made it unreachable. */ - if ((StmtFlags1 & SF_MASK_UNREACH) != SF_NONE && - (StmtFlags2 & SF_MASK_LABEL) == SF_NONE) { + if (!Unreachable) { + Unreachable = SF_Unreach (StmtFlags1); + } + /* If the previous statement made this one unreachable, but + ** this one has a label, it is not unreachable. + */ + if (Unreachable && SF_Label (StmtFlags2)) { + Unreachable = 0; + } + /* If this statement is unreachable but not the empty + ** statement, output a warning. + */ + if (Unreachable && !SF_Empty (StmtFlags2)) { LIUnreachableCodeWarning (LI2); UnreachableWarning = 1; } @@ -873,7 +885,7 @@ int AnyStatement (int* PendingToken, struct SwitchCtrl* Switch) case TOK_SEMI: /* Empty statement. Ignore it */ CheckSemi (PendingToken); - StmtFlags = SF_NONE; + StmtFlags = SF_EMPTY; break; case TOK_LCURLY: diff --git a/src/cc65/stmt.h b/src/cc65/stmt.h index eaaf235d5..4981a9b53 100644 --- a/src/cc65/stmt.h +++ b/src/cc65/stmt.h @@ -88,6 +88,9 @@ enum { SF_LABEL_CASE = 0x20000, /* Statement preceeded by case label */ SF_LABEL_DEFAULT = 0x40000, /* Statement preceeded by default label */ SF_MASK_LABEL = 0x70000, /* Mask for any label */ + + /* And a flag to mark an empty statement */ + SF_EMPTY = 0x80000, /* Empty statement */ }; /* Forward */ @@ -137,6 +140,12 @@ static inline int SF_Label (int F) return (F & SF_MASK_LABEL); } +static inline int SF_Empty (int F) +/* Check if this is the empty statement */ +{ + return (F & SF_EMPTY); +} + /*****************************************************************************/ diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index 591c893a4..295771bc9 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -393,8 +393,8 @@ void SwitchBodyStatement (struct SwitchCtrl* S, LineInfo* LI, int StmtFlags) /* Handle code without a label in the switch */ if (SC_Label (S) == SC_NONE) { /* This is a statement that preceedes any switch labels. If the - ** switch is not already marked as weird, output and the current - ** statement has no label, output a warning about unreachable code. + ** switch is not already marked as weird and the current statement + ** has no label, output a warning about unreachable code. */ if (!SC_IsWeird (S)) { if (!SF_Label (StmtFlags)) {