In switch statements, do only print a warning about missing case labels if

there are no regular labels and no default label.


git-svn-id: svn://svn.cc65.org/cc65/trunk@467 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2000-11-22 12:02:15 +00:00
parent 9398c5cef0
commit 596068b4ce

View File

@@ -265,24 +265,26 @@ static void docontinue (void)
static void cascadeswitch (struct expent* eval) static void cascadeswitch (struct expent* eval)
/* Handle a switch statement for chars with a cmp cascade for the selector */ /* Handle a switch statement for chars with a cmp cascade for the selector */
{ {
unsigned exitlab; /* Exit label */ unsigned ExitLab; /* Exit label */
unsigned nextlab; /* Next case label */ unsigned NextLab; /* Next case label */
unsigned codelab; /* Label that starts the actual selector code */ unsigned CodeLab; /* Label that starts the actual selector code */
int havebreak; /* Remember if we exited with break */ int HaveBreak; /* Remember if we exited with break */
int HaveDefault; /* Remember if we had a default label */
int lcount; /* Label count */ int lcount; /* Label count */
unsigned flags; /* Code generator flags */ unsigned Flags; /* Code generator flags */
struct expent lval; /* Case label expression */ struct expent lval; /* Case label expression */
long val; /* Case label value */ long Val; /* Case label value */
/* Create a loop so we may break out, init labels */ /* Create a loop so we may break out, init labels */
exitlab = GetLabel (); ExitLab = GetLabel ();
AddLoop (oursp, 0, exitlab, 0, 0); AddLoop (oursp, 0, ExitLab, 0, 0);
/* Setup some variables needed in the loop below */ /* Setup some variables needed in the loop below */
flags = TypeOf (eval->e_tptr) | CF_CONST | CF_FORCECHAR; Flags = TypeOf (eval->e_tptr) | CF_CONST | CF_FORCECHAR;
codelab = nextlab = 0; CodeLab = NextLab = 0;
havebreak = 1; HaveBreak = 1;
HaveDefault = 0;
/* Parse the labels */ /* Parse the labels */
lcount = 0; lcount = 0;
@@ -293,18 +295,18 @@ static void cascadeswitch (struct expent* eval)
/* If the code for the previous selector did not end with a /* If the code for the previous selector did not end with a
* break statement, we must jump over the next selector test. * break statement, we must jump over the next selector test.
*/ */
if (!havebreak) { if (!HaveBreak) {
/* Define a label for the code */ /* Define a label for the code */
if (codelab == 0) { if (CodeLab == 0) {
codelab = GetLabel (); CodeLab = GetLabel ();
} }
g_jump (codelab); g_jump (CodeLab);
} }
/* If we have a cascade label, emit it */ /* If we have a cascade label, emit it */
if (nextlab) { if (NextLab) {
g_defloclabel (nextlab); g_defloclabel (NextLab);
nextlab = 0; NextLab = 0;
} }
while (curtok == TOK_CASE || curtok == TOK_DEFAULT) { while (curtok == TOK_CASE || curtok == TOK_DEFAULT) {
@@ -325,30 +327,30 @@ static void cascadeswitch (struct expent* eval)
} }
/* Check the range of the expression */ /* Check the range of the expression */
val = lval.e_const; Val = lval.e_const;
switch (*eval->e_tptr) { switch (*eval->e_tptr) {
case T_SCHAR: case T_SCHAR:
/* Signed char */ /* Signed char */
if (val < -128 || val > 127) { if (Val < -128 || Val > 127) {
Error ("Range error"); Error ("Range error");
} }
break; break;
case T_UCHAR: case T_UCHAR:
if (val < 0 || val > 255) { if (Val < 0 || Val > 255) {
Error ("Range error"); Error ("Range error");
} }
break; break;
case T_INT: case T_INT:
if (val < -32768 || val > 32767) { if (Val < -32768 || Val > 32767) {
Error ("Range error"); Error ("Range error");
} }
break; break;
case T_UINT: case T_UINT:
if (val < 0 || val > 65535) { if (Val < 0 || Val > 65535) {
Error ("Range error"); Error ("Range error");
} }
break; break;
@@ -361,23 +363,23 @@ static void cascadeswitch (struct expent* eval)
ConsumeColon (); ConsumeColon ();
/* Emit a compare */ /* Emit a compare */
g_cmp (flags, val); g_cmp (Flags, Val);
/* If another case follows, we will jump to the code if /* If another case follows, we will jump to the code if
* the condition is true. * the condition is true.
*/ */
if (curtok == TOK_CASE) { if (curtok == TOK_CASE) {
/* Create a code label if needed */ /* Create a code label if needed */
if (codelab == 0) { if (CodeLab == 0) {
codelab = GetLabel (); CodeLab = GetLabel ();
} }
g_falsejump (CF_NONE, codelab); g_falsejump (CF_NONE, CodeLab);
} else if (curtok != TOK_DEFAULT) { } else if (curtok != TOK_DEFAULT) {
/* No case follows, jump to next selector */ /* No case follows, jump to next selector */
if (nextlab == 0) { if (NextLab == 0) {
nextlab = GetLabel (); NextLab = GetLabel ();
} }
g_truejump (CF_NONE, nextlab); g_truejump (CF_NONE, NextLab);
} }
} else { } else {
@@ -390,11 +392,14 @@ static void cascadeswitch (struct expent* eval)
/* Handle the pathologic case: DEFAULT followed by CASE */ /* Handle the pathologic case: DEFAULT followed by CASE */
if (curtok == TOK_CASE) { if (curtok == TOK_CASE) {
if (codelab == 0) { if (CodeLab == 0) {
codelab = GetLabel (); CodeLab = GetLabel ();
} }
g_jump (codelab); g_jump (CodeLab);
} }
/* Remember that we had a default label */
HaveDefault = 1;
} }
} }
@@ -402,19 +407,19 @@ static void cascadeswitch (struct expent* eval)
} }
/* Emit a code label if we have one */ /* Emit a code label if we have one */
if (codelab) { if (CodeLab) {
g_defloclabel (codelab); g_defloclabel (CodeLab);
codelab = 0; CodeLab = 0;
} }
/* Parse statements */ /* Parse statements */
if (curtok != TOK_RCURLY) { if (curtok != TOK_RCURLY) {
havebreak = statement (); HaveBreak = statement ();
} }
} }
/* Check if we have any labels */ /* Check if we have any labels */
if (lcount == 0) { if (lcount == 0 && !HaveDefault) {
Warning ("No case labels"); Warning ("No case labels");
} }
@@ -424,10 +429,10 @@ static void cascadeswitch (struct expent* eval)
/* Define the exit label and, if there's a next label left, create this /* Define the exit label and, if there's a next label left, create this
* one, too. * one, too.
*/ */
if (nextlab) { if (NextLab) {
g_defloclabel (nextlab); g_defloclabel (NextLab);
} }
g_defloclabel (exitlab); g_defloclabel (ExitLab);
/* End the loop */ /* End the loop */
DelLoop (); DelLoop ();
@@ -449,8 +454,9 @@ static void tableswitch (struct expent* eval)
int label; /* label for case */ int label; /* label for case */
int lcase; /* label for compares */ int lcase; /* label for compares */
int lcount; /* Label count */ int lcount; /* Label count */
int havebreak; /* Last statement has a break */ int HaveBreak; /* Last statement has a break */
unsigned flags; /* Code generator flags */ int HaveDefault; /* Remember if we had a default label */
unsigned Flags; /* Code generator flags */
struct expent lval; /* Case label expression */ struct expent lval; /* Case label expression */
struct swent *p; struct swent *p;
struct swent *swtab; struct swent *swtab;
@@ -459,7 +465,8 @@ static void tableswitch (struct expent* eval)
swtab = xmalloc (CASE_MAX * sizeof (struct swent)); swtab = xmalloc (CASE_MAX * sizeof (struct swent));
/* Create a look so we may break out, init labels */ /* Create a look so we may break out, init labels */
havebreak = 0; /* Keep gcc silent */ HaveBreak = 0; /* Keep gcc silent */
HaveDefault = 0; /* No default case until now */
dlabel = 0; /* init */ dlabel = 0; /* init */
lab = GetLabel (); /* get exit */ lab = GetLabel (); /* get exit */
p = swtab; p = swtab;
@@ -488,19 +495,20 @@ static void tableswitch (struct expent* eval)
} else { } else {
NextToken (); NextToken ();
dlabel = label; dlabel = label;
HaveDefault = 1;
} }
ConsumeColon (); ConsumeColon ();
} while (curtok == TOK_CASE || curtok == TOK_DEFAULT); } while (curtok == TOK_CASE || curtok == TOK_DEFAULT);
g_defloclabel (label); g_defloclabel (label);
havebreak = 0; HaveBreak = 0;
} }
if (curtok != TOK_RCURLY) { if (curtok != TOK_RCURLY) {
havebreak = statement (); HaveBreak = statement ();
} }
} }
/* Check if we have any labels */ /* Check if we have any labels */
if (lcount == 0) { if (lcount == 0 && !HaveDefault) {
Warning ("No case labels"); Warning ("No case labels");
} }
@@ -508,7 +516,7 @@ static void tableswitch (struct expent* eval)
NextToken (); NextToken ();
/* If the last statement doesn't have a break or return, add one */ /* If the last statement doesn't have a break or return, add one */
if (!havebreak) { if (!HaveBreak) {
g_jump (lab); g_jump (lab);
} }
@@ -516,8 +524,8 @@ static void tableswitch (struct expent* eval)
g_defloclabel (lcase); g_defloclabel (lcase);
/* Create the call to the switch subroutine */ /* Create the call to the switch subroutine */
flags = TypeOf (eval->e_tptr); Flags = TypeOf (eval->e_tptr);
g_switch (flags); g_switch (Flags);
/* First entry is negative of label count */ /* First entry is negative of label count */
g_defdata (CF_INT | CF_CONST, -((int)lcount)-1, 0); g_defdata (CF_INT | CF_CONST, -((int)lcount)-1, 0);
@@ -526,7 +534,7 @@ static void tableswitch (struct expent* eval)
AddCodeHint ("casetable"); AddCodeHint ("casetable");
p = swtab; p = swtab;
while (lcount) { while (lcount) {
g_case (flags, p->sw_lab, p->sw_const); /* Create one label */ g_case (Flags, p->sw_lab, p->sw_const); /* Create one label */
--lcount; --lcount;
++p; ++p;
} }