Fix the "double semicolon" problem where a double semicolon after a statement
that makes the following code unreachable led to an "unreachable code" warning.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user