From here:
http://lists.gnu.org/archive/html/tinycc-devel/2005-01/msg00013.html
Fixes a problem with sign extension in certain conversions.
diff -p tcc-0.9.22-orig/tcc.c tcc-0.9.22/tcc.c
*** tcc-0.9.22-orig/tcc.c Mon Nov 8 12:47:16 2004
--- tcc-0.9.22/tcc.c Tue Jan 25 14:25:33 2005
*************** void force_charshort_cast(int t)
*** 5613,5618 ****
--- 5613,5623 ----
bits = 32 - bits;
vpushi(bits);
gen_op(TOK_SHL);
+ /* result must be signed or the SAR is converted to an SHL
+ This was not the case when "t" was a signed short
+ and the last value on the stack was an unsigned int
+ */
+ vtop->type.t &= (~VT_UNSIGNED);
vpushi(bits);
gen_op(TOK_SAR);
}
diff -p tcc-0.9.22-orig/tcctest.c tcc-0.9.22/tcctest.c
*** tcc-0.9.22-orig/tcctest.c Mon Nov 8 12:47:16 2004
--- tcc-0.9.22/tcctest.c Tue Jan 25 14:17:28 2005
*************** void cast_test()
*** 1058,1063 ****
--- 1058,1065 ----
int a;
char c;
char tab[10];
+ unsigned b,d;
+ short s;
printf("cast_test:\n");
a = 0xfffff;
*************** void cast_test()
*** 1081,1086 ****
--- 1083,1096 ----
printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
+ /* test cast from unsigned to signed short to int */
+ b = 0xf000;
+ d = (short)b;
+ printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
+ b = 0xf0f0;
+ d = (char)b;
+ printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
+
/* test implicit int casting for array accesses */
c = 0;
tab[1] = 2;