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) {
|
if (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) {
|
||||||
LineInfo* LI1 = UseLineInfo (GetDiagnosticLI ());
|
LineInfo* LI1 = UseLineInfo (GetDiagnosticLI ());
|
||||||
int StmtFlags1 = AnyStatement (0, Switch);
|
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) {
|
while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) {
|
||||||
LineInfo* LI2 = UseLineInfo (GetDiagnosticLI ());
|
LineInfo* LI2 = UseLineInfo (GetDiagnosticLI ());
|
||||||
int StmtFlags2 = AnyStatement (0, Switch);
|
int StmtFlags2 = AnyStatement (0, Switch);
|
||||||
if (!UnreachableWarning) {
|
if (!UnreachableWarning) {
|
||||||
/* Check if the code is unreachable because of a preceeding
|
/* If this statement is not already unreachable, check if the
|
||||||
** jump and if the code doesn't have a jump label.
|
** previous statement made it unreachable.
|
||||||
*/
|
*/
|
||||||
if ((StmtFlags1 & SF_MASK_UNREACH) != SF_NONE &&
|
if (!Unreachable) {
|
||||||
(StmtFlags2 & SF_MASK_LABEL) == SF_NONE) {
|
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);
|
LIUnreachableCodeWarning (LI2);
|
||||||
UnreachableWarning = 1;
|
UnreachableWarning = 1;
|
||||||
}
|
}
|
||||||
@@ -873,7 +885,7 @@ int AnyStatement (int* PendingToken, struct SwitchCtrl* Switch)
|
|||||||
case TOK_SEMI:
|
case TOK_SEMI:
|
||||||
/* Empty statement. Ignore it */
|
/* Empty statement. Ignore it */
|
||||||
CheckSemi (PendingToken);
|
CheckSemi (PendingToken);
|
||||||
StmtFlags = SF_NONE;
|
StmtFlags = SF_EMPTY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_LCURLY:
|
case TOK_LCURLY:
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ enum {
|
|||||||
SF_LABEL_CASE = 0x20000, /* Statement preceeded by case label */
|
SF_LABEL_CASE = 0x20000, /* Statement preceeded by case label */
|
||||||
SF_LABEL_DEFAULT = 0x40000, /* Statement preceeded by default label */
|
SF_LABEL_DEFAULT = 0x40000, /* Statement preceeded by default label */
|
||||||
SF_MASK_LABEL = 0x70000, /* Mask for any label */
|
SF_MASK_LABEL = 0x70000, /* Mask for any label */
|
||||||
|
|
||||||
|
/* And a flag to mark an empty statement */
|
||||||
|
SF_EMPTY = 0x80000, /* Empty statement */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Forward */
|
/* Forward */
|
||||||
@@ -137,6 +140,12 @@ static inline int SF_Label (int F)
|
|||||||
return (F & SF_MASK_LABEL);
|
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 */
|
/* Handle code without a label in the switch */
|
||||||
if (SC_Label (S) == SC_NONE) {
|
if (SC_Label (S) == SC_NONE) {
|
||||||
/* This is a statement that preceedes any switch labels. If the
|
/* This is a statement that preceedes any switch labels. If the
|
||||||
** switch is not already marked as weird, output and the current
|
** switch is not already marked as weird and the current statement
|
||||||
** statement has no label, output a warning about unreachable code.
|
** has no label, output a warning about unreachable code.
|
||||||
*/
|
*/
|
||||||
if (!SC_IsWeird (S)) {
|
if (!SC_IsWeird (S)) {
|
||||||
if (!SF_Label (StmtFlags)) {
|
if (!SF_Label (StmtFlags)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user