thorinn@DIKU.DK (Lars Henrik Mathiesen) (09/12/89)
Viz.
skinfaxe% cat tst.c
main()
{
unsigned char c;
int i;
for (i = 127; i < 130; i++)
switch(c = i) {
case 127:
case 128:
case 129:
printf("%d\n", c);
break;
default:
printf("default %d\n", c);
}
}
skinfaxe% gcc -v -dr -O -traditional -o tst tst.c
gcc version 1.35
/usr/lib/gnu/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ -traditional tst.c /tmp/cca01424.cpp
GNU CPP version 1.35
/usr/lib/gnu/gcc-cc1 /tmp/cca01424.cpp -quiet -dumpbase tst.c -dr -O -traditional -version -o /tmp/cca01424.s
GNU C version 1.35 (sparc) compiled by GNU C version 1.35.
as -o tst.o /tmp/cca01424.s
ld -o tst -e start -dc -dp /lib/crt0.o tst.o /usr/lib/gnu/gcc-gnulib -lc
skinfaxe% tst
127
default 128
default 129
skinfaxe% cat tst.c.rtl
;; Function main
(note 1 0 2 "" NOTE_INSN_DELETED)
(note 2 1 3 "" NOTE_INSN_BLOCK_BEG)
(insn 3 2 4 (set (reg/v:SI 65)
(const_int 127)) -1 (nil)
(nil))
(note 4 3 46 "" NOTE_INSN_LOOP_BEG)
(jump_insn 46 4 47 (set (pc)
(label_ref 5)) -1 (nil)
(nil))
(barrier 47 46 45)
(code_label 45 47 8 11)
(note 8 45 30 "" NOTE_INSN_DELETED)
(insn 30 8 31 (set (reg/v:QI 64)
(subreg:QI (reg/v:SI 65) 0)) -1 (nil)
(nil))
(insn 31 30 32 (set (reg:SI 68)
(sign_extend:SI (reg/v:QI 64))) -1 (nil)
(nil))
(insn 32 31 33 (set (reg:SI 69)
(const_int 129)) -1 (nil)
(nil))
(insn 33 32 34 (set (cc0)
(compare (reg:SI 68)
(reg:SI 69))) -1 (nil)
(nil))
(jump_insn 34 33 35 (set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
(label_ref 22)
(pc))) -1 (nil)
(nil))
(insn 35 34 36 (set (reg:SI 70)
(sign_extend:SI (reg/v:QI 64))) -1 (nil)
(nil))
(insn 36 35 37 (set (reg:SI 71)
(const_int 127)) -1 (nil)
(nil))
(insn 37 36 38 (set (cc0)
(compare (reg:SI 70)
(reg:SI 71))) -1 (nil)
(nil))
(jump_insn 38 37 39 (set (pc)
(if_then_else (geu (cc0)
(const_int 0))
(label_ref 10)
(pc))) -1 (nil)
(nil))
(jump_insn 39 38 40 (set (pc)
(label_ref 22)) -1 (nil)
(nil))
(barrier 40 39 9)
.
.
.
.
skinfaxe%
As seen in insns 31 and 35, a sign-extend is generated for the switch
value, even though it is unsigned. This only happens when
-traditional is used.
The problem seems to be in stmt.c, function emit_case_nodes(). For a
single-valued case the parameter unsignedp is transmitted to
emit_cmp_insn() through the call of do_jump_if_equal(). For case
ranges emit_cmp_insn() is called directly with an argument of 0.
I don't understand the type system well enough to be sure that
`fixing' this is safe, but it sure looks like it needs fixing.
--
Lars Mathiesen, DIKU, U of Copenhagen, Denmark [uunet!]mcvax!diku!thorinn
Institute of Datalogy -- we're scientists, not engineers. thorinn@diku.dk