On 7/5/06, PerfectDark <[EMAIL PROTECTED] > wrote:This is known bug and I didnt heard that it was fixed by someone. I tested tcc mostly under win32 and code like that always lead to crush:
//--------------------
long long g_llSomethingVariable = -1LL;
#include <stdio.h>
int main( int argc, char ** argv )
{
return 0;
}
//--------------------
I've attached a patch to tcc-0.9.23 that should fix it. I haven't run too many tests but the one above works.
-Ben
*** tcc.c.orig Fri Jul 7 17:08:06 2006
--- tcc.c Fri Jul 7 17:26:04 2006
*************** void gen_opif(int op)
*** 5469,5474 ****
--- 5469,5550 ----
}
}
+ /* handle long long ops with constant propogation */
+ void gen_opil(int op)
+ {
+ int c1, c2, n;
+ SValue *v1, *v2;
+ int ifc;
+ long long int fc;
+ unsigned long long int ufc;
+
+ v1 = vtop - 1;
+ v2 = vtop;
+ /* currently, we cannot do computations with forward symbols */
+ c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ if (c1 && c2) {
+ fc = v2->c.ll;
+ ifc = v2->c.i;
+ ufc = v2->c.ull;
+ switch(op) {
+ case '+': v1->c.ll += fc; break;
+ case '-': v1->c.ll -= fc; break;
+ case '&': v1->c.ll &= fc; break;
+ case '^': v1->c.ll ^= fc; break;
+ case '|': v1->c.ll |= fc; break;
+ case '*': v1->c.ll *= fc; break;
+
+ case TOK_PDIV:
+ case '/':
+ case '%':
+ case TOK_UDIV:
+ case TOK_UMOD:
+ /* if division by zero, generate explicit division */
+ if (fc == 0) {
+ if (const_wanted)
+ error("division by zero in constant");
+ goto general_case;
+ }
+ switch(op) {
+ default: v1->c.ll /= fc; break;
+ case '%': v1->c.ll %= fc; break;
+ case TOK_UDIV: v1->c.ll = v1->c.ull / fc; break;
+ case TOK_UMOD: v1->c.ll = v1->c.ull % fc; break;
+ }
+ break;
+ case TOK_SHL: v1->c.ll <<= ifc; break;
+ case TOK_SHR: v1->c.ll = v1->c.ull >> ifc; break;
+ case TOK_SAR: v1->c.ll >>= ifc; break;
+ /* tests */
+ case TOK_ULT: v1->c.i = v1->c.ull < ufc; break;
+ case TOK_UGE: v1->c.i = v1->c.ull >= ufc; break;
+ case TOK_EQ: v1->c.i = v1->c.ll == fc; break;
+ case TOK_NE: v1->c.i = v1->c.ll != fc; break;
+ case TOK_ULE: v1->c.i = v1->c.ull <= ufc; break;
+ case TOK_UGT: v1->c.i = v1->c.ull > ufc; break;
+ case TOK_LT: v1->c.i = v1->c.ll < fc; break;
+ case TOK_GE: v1->c.i = v1->c.ll >= fc; break;
+ case TOK_LE: v1->c.i = v1->c.ll <= fc; break;
+ case TOK_GT: v1->c.i = v1->c.ll > fc; break;
+ /* logical */
+ case TOK_LAND: v1->c.ll = v1->c.ll && fc; break;
+ case TOK_LOR: v1->c.ll = v1->c.ll || fc; break;
+ default:
+ goto general_case;
+ }
+ vtop--;
+ } else {
+ general_case:
+ if (!nocode_wanted) {
+ /* call low level op generator */
+ gen_opl(op);
+ } else {
+ vtop--;
+ }
+ }
+ }
+
static int pointed_size(CType *type)
{
int align;
*************** void gen_op(int op)
*** 5661,5667 ****
if (is_float(t))
gen_opif(op);
else if ((t & VT_BTYPE) == VT_LLONG)
! gen_opl(op);
else
gen_opic(op);
if (op >= TOK_ULT && op <= TOK_GT) {
--- 5737,5743 ----
if (is_float(t))
gen_opif(op);
else if ((t & VT_BTYPE) == VT_LLONG)
! gen_opil(op);
else
gen_opic(op);
if (op >= TOK_ULT && op <= TOK_GT) {
_______________________________________________ Tinycc-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/tinycc-devel
