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

Reply via email to