X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fswstmt.c;h=c7446c0202eecfe2d45c88ca9cb5658b54577734;hb=98da4b581175232d89630f5c19f22e37a7588c7b;hp=fc4d40a6362ff565f2831772d543f3540b006a83;hpb=3b5808788bed043ae26f562649363668085272e0;p=cc65 diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index fc4d40a63..c7446c020 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -73,7 +73,8 @@ void SwitchStatement (void) unsigned ExitLabel; /* Exit label */ unsigned CaseLabel; /* Label for case */ unsigned DefaultLabel; /* Label for the default branch */ - long Val; /* Case label value */ + long Val; /* Case label value */ + int HaveBreak = 0; /* True if the last statement had a break */ /* Eat the "switch" token */ @@ -200,7 +201,7 @@ void SwitchStatement (void) /* Parse statements */ if (CurTok.Tok != TOK_RCURLY) { - Statement (0); + HaveBreak = Statement (0); } } @@ -210,9 +211,22 @@ void SwitchStatement (void) Warning ("No case labels"); } else { + + CodeMark SwitchCodeStart; + + /* If the last statement did not have a break, we may have an open + * label (maybe from an if or similar). Emitting code and then moving + * this code to the top will also move the label to the top which is + * wrong. So if the last statement did not have a break (which would + * carry the label), add a jump to the exit. If it is useless, the + * optimizer will remove it later. + */ + if (!HaveBreak) { + g_jump (ExitLabel); + } /* Remember the current position */ - CodeMark SwitchCodeStart = GetCodePos(); + SwitchCodeStart = GetCodePos(); /* Generate code */ g_switch (Nodes, DefaultLabel? DefaultLabel : ExitLabel, Depth);