#595 unmatched switch causes jump to a random location

Erik Petrich
Stas Sergeev


There seem to be a bug in sdcc which causes a jump
to a random location when the "switch" without a
"default" case is unmatched.

Attached is a test program. Also here it is:
#include <at89S8252.h> /* special function register
declarations */

int main()
char a, b;
b = SBUF;
switch (b) {
case 1: a = 'a';
case 2: a = 'b';
return a;

The code it generates, looks as follows:
;switch.c:7: switch (b) {
; genMinus
; genMinusDec
dec r2
; genJumpTab
mov a,r2
add a,acc
add a,r2
mov dptr,#00106$
jmp @a+dptr
ljmp 00101$
ljmp 00102$
C$switch.c$8$2$2 ==.
;switch.c:8: case 1: a = 'a';

Now, as "b" contains some garbage and there is no a
"default" case, the "switch" must be bypassed.
But instead it is being performed, and the ljmp
misses a jump table with an unpredictable results.


  • Stas Sergeev
    Stas Sergeev

    a test case

  • Stas Sergeev
    Stas Sergeev

    • labels: --> mcs51(8051) target
  • Stas Sergeev
    Stas Sergeev

    Logged In: YES

    Compile the test-case on a latest sdcc from CVS with the
    following command line:
    sdcc -mmcs51 --nojtbound --noinduction --noloopreverse
    --xram-size 0 --code-size 8192 --debug --no-peep switch.c

  • Erik Petrich
    Erik Petrich

    Logged In: YES

    Unless I am overlooking your point, the compiler appears to
    work as designed.

    If you specify --nojtbound, the compiler omits the code that
    verifies that the switched value is within the range of
    cases handled in the switch statement. Essentially, by using
    --nojtbound you are making a promise to the compiler that
    you have already (by some other means) ensured that your
    value is within the range of cases given; in exchange, the
    compiler generates faster and shorter code. Your sample test
    case breaks this promise and so will fail when b<1 or b>2.

    Perhaps the option's name has tricked you? Whereas most of
    the --no_x_ options turn OFF an optimization, the
    --nojtbound option turns one ON.

  • Erik Petrich
    Erik Petrich

    • milestone: --> non_bugs
    • assigned_to: nobody --> epetrich
    • status: open --> closed-rejected
  • Stas Sergeev
    Stas Sergeev

    Logged In: YES

    You are not overlooking my point - thanks for the
    clarifications. Now looking in the docs I see this
    option is not recommended to be used at all.
    What really tricked me is that I never expected that
    some option will make a compiller to violate the
    standards, so I strongly supposed that it must behave
    nearly identically with any options. Now I see it is not.
    The reason for using that option was that otherwise some
    programs exceed the 8K limit (whilst compilled with a
    Franklin Software' compiller they take only 5K and without
    any deviations - probably a little better optimisation).
    I think sdcc, when invoked without args (printing help)
    must print some warning about that particular option, as
    this option is dangerous while the others are not supposed
    to be (or are they?).
    It seems like I will have to optimize our programs
    by hands before they can be compilled with sdcc, to feet
    them in 8K again, which is not very good either...
    The reason why I am using a --no-peep btw, is that I am
    sure I've seen it "optimizing" a jump table, making it
    non-functional (removed redundant jumps, replaced ljmp
    with sjmp etc), but on a simple test cases this doesn't
    seem to happen.