Many signedness and type propagation fixes
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 1 Jan 2004 21:59:26 +0000 (21:59 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 1 Jan 2004 21:59:26 +0000 (21:59 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3072 4a8a32a2-be11-0410-ad9d-d568d2c75423

.version
ChangeLog
src/SDCCast.c
src/SDCCicode.c
src/SDCCicode.h
src/SDCCsymt.c
src/SDCCsymt.h
src/SDCCval.c
src/hc08/ralloc.c
support/regression/tests/ast_constant_folding.c
support/regression/tests/literalop.c

index e75da3e63d60425514e3bd5d5876289e4322c5ae..00355e29d11ac4a7ee62410face3b0adb50201ac 100644 (file)
--- a/.version
+++ b/.version
@@ -1 +1 @@
-2.3.6
+2.3.7
index ef4db4fb336a33e67214cde31188605565869aba..c6d252c523a823d0dfe65b95dd1dabab4f311e53 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2004-01-01 Bernhard Held <bernhard@bernhardheld.de>
+
+       Many signedness and type propagation fixes:
+       * src/SDCCicode.c: made geniCodeCast() static
+       replaced SPEC_ by IS_ (cosmetic)
+       (operandOperation): fixed div and mod operation
+       (usualBinaryConversions): added support for promotion of char
+       (geniCodeMultiply): replaced (unsigned long) by (TYPE_UDWORD)
+       (geniCodeDivision): replaced (unsigned long) by (TYPE_UDWORD)
+       (geniCodeAdd): an array index will stay unsigned, even if promoted
+       from char to int
+       (geniCodeArray): ditto
+       * src/SDCCicode.h: made geniCodeCast() static: removed prototype
+       * src/SDCCsymt.c (computeType): added more support for char;
+       promotion of char is selectable by promoteCharToInt, fixed signedness
+       for all cases
+       (powof2): replaced (unsigned long) by (TYPE_UDWORD)
+       * src/SDCCsymt.h (powof2): replaced (unsigned long) by (TYPE_UDWORD)
+       * src/SDCCval (val*): replaced signedness calculation by
+       computeType()
+       rearranged if-branches (cosmetic)
+       (valShift): added warning W_SHIFT_CHANGED
+       (valCompare): fixed problem with different types
+       * src/hc08/rallo.c (leastUsedLR): fixed gcc 3.3 warning
+       * support/regression/tests/literalop.c: added many cases
+       * support/regression/tests/ast_constant_folding.c: changed finally to
+       'unsigned int'
+       * .version: new year, new version: 2.3.7
+
 2004-01-01 Erik Petrich <epetrich@ivorytower.norman.ok.us>
 
        * src/SDCCsymt.h: missing from yesterday's commits
@@ -22,7 +51,7 @@
 
 2003-12-22 Frieder Ferlemann <Frieder.Ferlemann@web.de>
 
-       * src/mcs51/gen.c (genPlus): added special handling for 256 byte 
+       * src/mcs51/gen.c (genPlus): added special handling for 256 byte
        aligned xdata arrays. Erik helped me with the if clause.
 
 2003-12-20 Erik Petrich <epetrich@ivorytower.norman.ok.us>
 
 2003-12-13 Frieder Ferlemann <Frieder.Ferlemann@web.de>
 
-       * src/mcs51/main.c: fixed bug #737001 for the mcs51. SDCC clears 
-       xdata and data memory on startup. Set the environment variable 
+       * src/mcs51/main.c: fixed bug #737001 for the mcs51. SDCC clears
+       xdata and data memory on startup. Set the environment variable
        SDCC_NOGENRAMCLEAR to disable this.
        * src/mcs51/peephole.def,
        * src/ds390/peephole.def: using the atomic test and clear instruction jbc
index 7a8bfc61e050f3f3d72585f92238abae3eb1659c..6974206c47e9d53b3f4177ffa9b000a9af4ec418 100644 (file)
@@ -344,7 +344,7 @@ hasSEFcalls (ast * tree)
 /*-----------------------------------------------------------------*/
 /* isAstEqual - compares two asts & returns 1 if they are equal    */
 /*-----------------------------------------------------------------*/
-int 
+static int
 isAstEqual (ast * t1, ast * t2)
 {
   if (!t1 && !t2)
@@ -2382,7 +2382,7 @@ decorateType (ast * tree)
          }
 
          TTYPE (tree) =
-           computeType (LTYPE (tree), RTYPE (tree));
+           computeType (LTYPE (tree), RTYPE (tree), FALSE);
          TETYPE (tree) = getSpec (TTYPE (tree));
 
           /* if left is a literal exchange left & right */
@@ -2595,7 +2595,8 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           FALSE));
 
       /*------------------------------------------------------------------*/
       /*----------------------------*/
@@ -2623,7 +2624,8 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           TRUE));
 
       /* if right is a literal and */
       /* left is also a division by a literal then */
@@ -2688,7 +2690,8 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           TRUE));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2800,13 +2803,16 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           TRUE));
 
       /* promote result to int if left & right are char
         this will facilitate hardware multiplies 8bit x 8bit = 16bit */
+      /* now done by computeType
       if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
        SPEC_NOUN(TETYPE(tree)) = V_INT;
       }
+      */
 
       return tree;
 
@@ -2937,7 +2943,8 @@ decorateType (ast * tree)
       else
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 computeType (LTYPE (tree),
-                                             RTYPE (tree)));
+                                             RTYPE (tree),
+                                             FALSE));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -3036,7 +3043,8 @@ decorateType (ast * tree)
       else
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 computeType (LTYPE (tree),
-                                             RTYPE (tree)));
+                                             RTYPE (tree),
+                                             FALSE));
 
       LRVAL (tree) = RRVAL (tree) = 1;
 
@@ -3459,16 +3467,18 @@ decorateType (ast * tree)
        }
       /* if unsigned value < 0  then always false */
       /* if (unsigned value) > 0 then (unsigned value) */
-      if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  && 
-         ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
-
-         if (tree->opval.op == '<') {
+      if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  &&
+         ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
+       {
+         if (tree->opval.op == '<')
+           {
              return tree->right;
-         }
-         if (tree->opval.op == '>') {
+           }
+         if (tree->opval.op == '>')
+           {
              return tree->left;
-         }
-      }
+           }
+        }
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) &&
@@ -3607,7 +3617,7 @@ decorateType (ast * tree)
          goto errorTreeReturn;
        }
 
-      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
+      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
       TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
@@ -3689,7 +3699,8 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           FALSE));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "-=");
@@ -3730,7 +3741,8 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           FALSE));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "+=");
@@ -5140,7 +5152,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                                fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
                        else
                                fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
-                       fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
+                       fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
                                                      floatFromVal(tree->opval.val));
                } else if (tree->opval.val->sym) {
                        /* if the undefined flag is set then give error message */
index b723c54116810e4fcfc3e4d25a8e3103bf5b2de6..a6a2193a5cbe7116fccc9e8d259bf759c97ede25 100644 (file)
@@ -53,6 +53,7 @@ operand *geniCodeRValue (operand *, bool);
 operand *geniCodeDerefPtr (operand *,int);
 int isLvaluereq(int lvl);
 void  setOClass (sym_link * ptr, sym_link * spec);
+static operand *geniCodeCast (sym_link *, operand *, bool);
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
 /* forward definition of ic print functions */
@@ -144,14 +145,14 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg,
 
   max = pow ((double)2.0, (double)bitsForType(ltype));
 
-  if (SPEC_LONG(val->type)) {
-    if (SPEC_USIGN(val->type)) {
+  if (IS_LONG(val->type)) {
+    if (IS_UNSIGNED(val->type)) {
       v=SPEC_CVAL(val->type).v_ulong;
     } else {
       v=SPEC_CVAL(val->type).v_long;
     }
   } else {
-    if (SPEC_USIGN(val->type)) {
+    if (IS_UNSIGNED(val->type)) {
       v=SPEC_CVAL(val->type).v_uint;
     } else {
       v=SPEC_CVAL(val->type).v_int;
@@ -165,21 +166,21 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg,
     pedantic=2;
 #endif
 
-  if (SPEC_NOUN(ltype)==FLOAT) {
+  if (IS_FLOAT(ltype)) {
     // anything will do
     return;
   }
 
-  if (!SPEC_USIGN(val->type) && v<0) {
+  if (!IS_UNSIGNED(val->type) && v<0) {
     negative=1;
-    if (SPEC_USIGN(ltype) && (pedantic>1)) {
+    if (IS_UNSIGNED(ltype) && (pedantic>1)) {
       warnings++;
     }
     v=-v;
   }
 
   // if very pedantic: "char c=200" is not allowed
-  if (pedantic>1 && !SPEC_USIGN(ltype)) {
+  if (pedantic>1 && !IS_UNSIGNED(ltype)) {
     max = max/2 + negative;
   }
 
@@ -190,7 +191,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg,
 #if 0 // temporary disabled, leaving the warning as a reminder
   if (warnings) {
     SNPRINTF (message, sizeof(message), "for %s %s in %s", 
-            SPEC_USIGN(ltype) ? "unsigned" : "signed",
+            IS_UNSIGNED(ltype) ? "unsigned" : "signed",
             nounName(ltype), msg);
     werror (W_CONST_RANGE, message);
 
@@ -222,7 +223,7 @@ printOperand (operand * op, FILE * file)
 
     case VALUE:
       opetype = getSpec (operandType (op));
-      if (SPEC_NOUN (opetype) == V_FLOAT)
+      if (IS_FLOAT (opetype))
        fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
       else
        fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
@@ -1065,7 +1066,7 @@ iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
        ic = ic->next;
        (*pcount)++;
     }
-    
+
     ic->generated = 1;
     /* make sure this is a builtin function call */
     assert(IS_SYMOP(IC_LEFT(ic)));
@@ -1123,14 +1124,14 @@ operandOperation (operand * left, operand * right,
           !IS_SPEC (type))
         {
          /* long is handled here, because it can overflow with double */
-         if (SPEC_LONG (type) ||
+         if (IS_LONG (type) ||
              !IS_SPEC (type))
          /* signed and unsigned mul are the same, as long as the precision
             of the result isn't bigger than the precision of the operands. */
            retval = operandFromValue (valCastLiteral (type,
                     (TYPE_UDWORD) operandLitValue (left) *
                     (TYPE_UDWORD) operandLitValue (right)));
-         else if (SPEC_USIGN (type)) /* unsigned int */
+         else if (IS_UNSIGNED (type)) /* unsigned int */
            {
              /* unsigned int is handled here in order to detect overflow */
              TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
@@ -1165,23 +1166,35 @@ operandOperation (operand * left, operand * right,
 
        }
       else
-       retval = operandFromValue (valCastLiteral (type,
-                                                  operandLitValue (left) /
-                                                  operandLitValue (right)));
+        {
+         if (IS_UNSIGNED (type))
+           {
+             SPEC_USIGN (let) = 1;
+             SPEC_USIGN (ret) = 1;
+             retval = operandFromValue (valCastLiteral (type,
+                                       (TYPE_UDWORD) operandLitValue (left) /
+                                       (TYPE_UDWORD) operandLitValue (right)));
+           }
+         else
+           {
+              retval = operandFromValue (valCastLiteral (type,
+                                                    operandLitValue (left) /
+                                                    operandLitValue (right)));
+           }
+       }
       break;
     case '%':
-      if ((TYPE_UDWORD) operandLitValue (right) == 0) {
+      if ((TYPE_UDWORD) operandLitValue (right) == 0)
+        {
          werror (E_DIVIDE_BY_ZERO);
          retval = right;
-      }
+        }
       else
         {
-          if (SPEC_USIGN(let) || SPEC_USIGN(ret))
-           /* one of the operands is unsigned */
+          if (IS_UNSIGNED (type))
            retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
                                     (TYPE_UDWORD) operandLitValue (right));
          else
-           /* both operands are signed */
            retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
                                     (TYPE_DWORD) operandLitValue (right));
         }
@@ -1195,7 +1208,7 @@ operandOperation (operand * left, operand * right,
     case RIGHT_OP:
       /* The number of right shifts is always unsigned. Signed doesn't make
         sense here. Shifting by a negative number is impossible. */
-      if (SPEC_USIGN(let))
+      if (IS_UNSIGNED(let))
         /* unsigned: logic shift right */
         retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
                                 (TYPE_UDWORD) operandLitValue (right));
@@ -1210,14 +1223,14 @@ operandOperation (operand * left, operand * right,
        TYPE_UDWORD l, r;
 
        l = (TYPE_UDWORD) operandLitValue (left);
-       if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
+       if (IS_CHAR(OP_VALUE(left)->type))
          l &= 0xff;
-       else if (!SPEC_LONG (OP_VALUE(left)->type))
+       else if (!IS_LONG (OP_VALUE(left)->type))
          l &= 0xffff;
        r = (TYPE_UDWORD) operandLitValue (right);
-       if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
+       if (IS_CHAR(OP_VALUE(right)->type))
          r &= 0xff;
-       else if (!SPEC_LONG (OP_VALUE(right)->type))
+       else if (!IS_LONG (OP_VALUE(right)->type))
          r &= 0xffff;
        retval = operandFromLit (l == r);
       }
@@ -1736,18 +1749,29 @@ usualUnaryConversions (operand * op)
 /*-----------------------------------------------------------------*/
 /* perform "usual binary conversions"                              */
 /*-----------------------------------------------------------------*/
-sym_link *
-usualBinaryConversions (operand ** op1, operand ** op2)
+static sym_link *
+usualBinaryConversions (operand ** op1, operand ** op2,
+                        bool promoteCharToInt, bool isMul)
 {
   sym_link *ctype;
   sym_link *rtype = operandType (*op2);
   sym_link *ltype = operandType (*op1);
-  
-  ctype = computeType (ltype, rtype);
+
+  ctype = computeType (ltype, rtype, promoteCharToInt);
+
+  /* special for multiplication:
+     This if for 'mul a,b', which takes two chars and returns an int */
+  if (   isMul
+      /* && promoteCharToInt   superfluous, already handled by computeType() */
+      && IS_CHAR (getSpec (ltype))
+      && IS_CHAR (getSpec (rtype))
+      && !(IS_UNSIGNED (getSpec (rtype)) ^ IS_UNSIGNED (getSpec (ltype)))
+      && IS_INT  (getSpec (ctype)))
+    return ctype;
 
   *op1 = geniCodeCast (ctype, *op1, TRUE);
   *op2 = geniCodeCast (ctype, *op2, TRUE);
-  
+
   return ctype;
 }
 
@@ -1812,7 +1836,7 @@ geniCodeRValue (operand * op, bool force)
 /*-----------------------------------------------------------------*/
 /* geniCodeCast - changes the value from one type to another       */
 /*-----------------------------------------------------------------*/
-operand *
+static operand *
 geniCodeCast (sym_link * type, operand * op, bool implicit)
 {
   iCode *ic;
@@ -1834,14 +1858,16 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
 
   /* if this is a literal then just change the type & return */
   if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
-    return operandFromValue (valCastLiteral (type,
-                                            operandLitValue (op)));
+    {
+      return operandFromValue (valCastLiteral (type,
+                                              operandLitValue (op)));
+    }
 
   /* if casting to/from pointers, do some checking */
   if (IS_PTR(type)) { // to a pointer
     if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
-      if (IS_INTEGRAL(optype)) { 
-       // maybe this is NULL, than it's ok. 
+      if (IS_INTEGRAL(optype)) {
+       // maybe this is NULL, than it's ok.
        if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
          if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
            // no way to set the storage
@@ -1857,9 +1883,9 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
            errors++;
          }
        }
-      }        else { 
+      }        else {
        // shouldn't do that with float, array or structure unless to void
-       if (!IS_VOID(getSpec(type)) && 
+       if (!IS_VOID(getSpec(type)) &&
            !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
          werror(E_INCOMPAT_TYPES);
          errors++;
@@ -1869,7 +1895,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
       if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
        // if not a pointer to a function
        if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
-         if (implicit) { // if not to generic, they have to match 
+         if (implicit) { // if not to generic, they have to match
            if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
              werror(E_INCOMPAT_PTYPES);
              errors++;
@@ -1903,11 +1929,10 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
       ((IS_SPEC (type) && IS_SPEC (optype)) ||
        (!IS_SPEC (type) && !IS_SPEC (optype))))
     {
-
       ic = newiCode ('=', NULL, op);
       IC_RESULT (ic) = newiTempOperand (type, 0);
       SPIL_LOC (IC_RESULT (ic)) =
-       (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
+        (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
       IC_RESULT (ic)->isaddr = 0;
     }
   else
@@ -1932,7 +1957,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
 /*-----------------------------------------------------------------*/
 /* geniCodeLabel - will create a Label                             */
 /*-----------------------------------------------------------------*/
-void 
+void
 geniCodeLabel (symbol * label)
 {
   iCode *ic;
@@ -1944,7 +1969,7 @@ geniCodeLabel (symbol * label)
 /*-----------------------------------------------------------------*/
 /* geniCodeGoto  - will create a Goto                              */
 /*-----------------------------------------------------------------*/
-void 
+void
 geniCodeGoto (symbol * label)
 {
   iCode *ic;
@@ -1957,7 +1982,7 @@ geniCodeGoto (symbol * label)
 /* geniCodeMultiply - gen intermediate code for multiplication     */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeMultiply (operand * left, operand * right,int resultIsInt)
+geniCodeMultiply (operand * left, operand * right, int resultIsInt)
 {
   iCode *ic;
   int p2 = 0;
@@ -1970,20 +1995,16 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt)
                                      right->operand.valOperand));
 
   if (IS_LITERAL(retype)) {
-    p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
+    p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
   }
 
-  resType = usualBinaryConversions (&left, &right);
+  resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
 #if 1
   rtype = operandType (right);
   retype = getSpec (rtype);
   ltype = operandType (left);
   letype = getSpec (ltype);
 #endif
-  if (resultIsInt)
-    {
-      SPEC_NOUN(getSpec(resType))=V_INT;
-    }
 
   /* if the right is a literal & power of 2 */
   /* then make it a left shift              */
@@ -2030,15 +2051,15 @@ geniCodeDivision (operand * left, operand * right)
   sym_link *ltype = operandType (left);
   sym_link *letype = getSpec (ltype);
 
-  resType = usualBinaryConversions (&left, &right);
+  resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
 
   /* if the right is a literal & power of 2
      and left is unsigned then make it a
      right shift */
   if (IS_LITERAL (retype) &&
       !IS_FLOAT (letype) &&
-      SPEC_USIGN(letype) &&
-      (p2 = powof2 ((unsigned long)
+      IS_UNSIGNED(letype) &&
+      (p2 = powof2 ((TYPE_UDWORD)
                    floatFromVal (right->operand.valOperand)))) {
     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
   }
@@ -2069,7 +2090,7 @@ geniCodeModulus (operand * left, operand * right)
     return operandFromValue (valMod (left->operand.valOperand,
                                     right->operand.valOperand));
 
-  resType = usualBinaryConversions (&left, &right);
+  resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
 
   /* now they are the same size */
   ic = newiCode ('%', left, right);
@@ -2148,7 +2169,7 @@ geniCodeSubtract (operand * left, operand * right)
     }
   else
     {                          /* make them the same size */
-      resType = usualBinaryConversions (&left, &right);
+      resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
     }
 
   ic = newiCode ('-', left, right);
@@ -2174,6 +2195,7 @@ geniCodeAdd (operand * left, operand * right, int lvl)
   sym_link *resType;
   operand *size;
   int isarray = 0;
+  bool indexUnsigned;
   LRTYPE;
 
   /* if the right side is LITERAL zero */
@@ -2190,15 +2212,22 @@ geniCodeAdd (operand * left, operand * right, int lvl)
     {
       isarray = left->isaddr;
       // there is no need to multiply with 1
-      if (getSize(ltype->next)!=1) {
-       size  = operandFromLit (getSize (ltype->next));
-       right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
-      }
+      if (getSize (ltype->next) != 1)
+        {
+         size  = operandFromLit (getSize (ltype->next));
+         indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
+         right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
+         /* Even if right is a 'unsigned char',
+            the result will be a 'signed int' due to the promotion rules.
+            It doesn't make sense when accessing arrays, so let's fix it here: */
+         if (indexUnsigned)
+           SPEC_USIGN (getSpec (operandType (right))) = 1;
+       }
       resType = copyLinkChain (ltype);
     }
   else
     { // make them the same size
-      resType = usualBinaryConversions (&left, &right);
+      resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
     }
 
   /* if they are both literals then we know */
@@ -2270,20 +2299,24 @@ geniCodeArray (operand * left, operand * right,int lvl)
 {
   iCode *ic;
   sym_link *ltype = operandType (left);
-  
+  bool indexUnsigned;
+
   if (IS_PTR (ltype))
     {
       if (IS_PTR (ltype->next) && left->isaddr)
        {
          left = geniCodeRValue (left, FALSE);
        }
-      
+
       return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
     }
-
+  indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
   right = geniCodeMultiply (right,
                            operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
-
+  /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
+     It doesn't make sense when accessing arrays, so let's fix it here: */
+  if (indexUnsigned)
+    SPEC_USIGN (getSpec (operandType (right))) = 1;
   /* we can check for limits here */
   if (isOperandLiteral (right) &&
       IS_ARRAY (ltype) &&
@@ -2308,7 +2341,7 @@ geniCodeArray (operand * left, operand * right,int lvl)
 }
 
 /*-----------------------------------------------------------------*/
-/* geniCodeStruct - generates intermediate code for structres      */
+/* geniCodeStruct - generates intermediate code for structures     */
 /*-----------------------------------------------------------------*/
 operand *
 geniCodeStruct (operand * left, operand * right, bool islval)
@@ -2779,7 +2812,7 @@ geniCodeLogic (operand * left, operand * right, int op)
         }
     }
 
-  ctype = usualBinaryConversions (&left, &right);
+  ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
 
   ic = newiCode (op, left, right);
   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
@@ -3347,7 +3380,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
       sym_link *cetype = getSpec (operandType (cond));
       /* no need to check the lower bound if
          the condition is unsigned & minimum value is zero */
-      if (!(min == 0 && SPEC_USIGN (cetype)))
+      if (!(min == 0 && IS_UNSIGNED (cetype)))
        {
          boundary = geniCodeLogic (cond, operandFromLit (min), '<');
          ic = newiCodeCondition (boundary, falseLabel, NULL);
index 8d6c543b5a64b34e2c4d1c370b079742e13a6b22..1822f79ff548c01c5ae1a28ce6e32fe86d094b88 100644 (file)
@@ -291,7 +291,6 @@ int isOperandVolatile (operand *, bool);
 int isOperandGlobal (operand *);
 void printiCChain (iCode *, FILE *);
 operand *ast2iCode (ast *,int);
-operand *geniCodeCast (sym_link *, operand *, bool);
 operand *geniCodePtrPtrSubtract (operand *, operand *);
 void initiCode ();
 iCode *iCodeFromAst (ast *);
index 14bcaee6f72dd93fbdc313ad35100c7c783f183c..78d03f4ff85f258ae6e4040f926f1bc17acd6790 100644 (file)
@@ -1338,7 +1338,7 @@ checkSClass (symbol * sym, int isProto)
       }
     }
   }
-  
+
   /* automatic symbols cannot be given   */
   /* an absolute address ignore it      */
   if (sym->level &&
@@ -1513,7 +1513,7 @@ cleanUpLevel (bucket ** table, int level)
 /* computeType - computes the resultant type from two types         */
 /*------------------------------------------------------------------*/
 sym_link *
-computeType (sym_link * type1, sym_link * type2)
+computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
 {
   sym_link *rType;
   sym_link *reType;
@@ -1546,14 +1546,18 @@ computeType (sym_link * type1, sym_link * type2)
     rType = copyLinkChain (type2);
 
   reType = getSpec (rType);
-#if 0
-  if (SPEC_NOUN (reType) == V_CHAR)
+
+  /* avoid conflicting types */
+  reType->select.s._signed = 0;
+
+  if (IS_CHAR (reType) && promoteCharToInt)
     SPEC_NOUN (reType) = V_INT;
-#endif
 
-  /* if either of them unsigned but not val then make this unsigned */
-  if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) &&
-      !IS_FLOAT (reType))
+  if (   (   (   SPEC_USIGN (etype1)
+             && (getSize (etype1) >= getSize (reType)))
+         || (   SPEC_USIGN (etype2)
+             && (getSize (etype2) >= getSize (reType))))
+      && !IS_FLOAT (reType))
     SPEC_USIGN (reType) = 1;
   else
     SPEC_USIGN (reType) = 0;
@@ -2628,8 +2632,8 @@ printTypeChainRaw (sym_link * start, FILE * of)
 /*-----------------------------------------------------------------*/
 /* powof2 - returns power of two for the number if number is pow 2 */
 /*-----------------------------------------------------------------*/
-int 
-powof2 (unsigned long num)
+int
+powof2 (TYPE_UDWORD num)
 {
   int nshifts = 0;
   int n1s = 0;
@@ -2672,7 +2676,7 @@ sym_link *floatType;
 static char *
 _mangleFunctionName(char *in)
 {
-  if (port->getMangledFunctionName) 
+  if (port->getMangledFunctionName)
     {
       return port->getMangledFunctionName(in);
     }
index 8632c1634de9ee987779615a05441a62712e0e93..f79b049322de30f01738d081eb6b4dd91341e24a 100644 (file)
@@ -539,10 +539,10 @@ int funcInChain (sym_link *);
 void addSymChain (symbol *);
 sym_link *structElemType (sym_link *, value *);
 symbol *getStructElement (structdef *, symbol *);
-sym_link *computeType (sym_link *, sym_link *);
+sym_link *computeType (sym_link *, sym_link *, bool promoteCharToInt);
 void processFuncArgs (symbol *);
 int isSymbolEqual (symbol *, symbol *);
-int powof2 (unsigned long);
+int powof2 (TYPE_UDWORD);
 void printTypeChain (sym_link *, FILE *);
 void printTypeChainRaw (sym_link *, FILE *);
 void initCSupport ();
index fbbf0c116a3f7c24d735d6d2e0088bbdf602d9eb..7c0e04da24e3f947e5fb44325a9c6fa01feeacfc 100644 (file)
@@ -268,7 +268,7 @@ list2expr (initList * ilist)
 /*------------------------------------------------------------------*/
 /* resolveIvalSym - resolve symbols in initial values               */
 /*------------------------------------------------------------------*/
-void 
+void
 resolveIvalSym (initList * ilist)
 {
   if (!ilist)
@@ -374,7 +374,7 @@ static value *cheapestVal (value *val) {
 
 static value *cheapestVal (value *val)
 {
-  /* - signed/unsigned must no be changed.
+  /* - signed/unsigned must not be changed.
      - long must not be changed.
 
      the only possible reduction is from signed int to signed char,
@@ -1088,18 +1088,9 @@ valMult (value * lval, value * rval)
                           IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
   SPEC_SCLS  (val->type) = S_LITERAL;  /* will remain literal */
   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
-  /* both signed char and unsigned char are promoted to signed int */
-  if (IS_CHAR (lval->etype))
-    {
-      SPEC_USIGN (lval->etype) = 0;
-      SPEC_NOUN  (lval->etype) = V_INT;
-    }
-  if (IS_CHAR (rval->etype))
-    {
-      SPEC_USIGN (rval->etype) = 0;
-      SPEC_NOUN  (rval->etype) = V_INT;
-    }
-  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
+  SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
+                                                   rval->etype,
+                                                   TRUE));
   if (IS_FLOAT (val->type))
     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
       /* signed and unsigned mul are the same, as long as the precision of the
@@ -1107,7 +1098,7 @@ valMult (value * lval, value * rval)
   else if (SPEC_LONG (val->type))
     SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
                                    (TYPE_UDWORD) floatFromVal (rval);
-  else if (SPEC_USIGN (val->type)) /* unsigned */
+  else if (SPEC_USIGN (val->type)) /* unsigned int */
     {
       TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
                        (TYPE_UWORD) floatFromVal (rval);
@@ -1116,7 +1107,7 @@ valMult (value * lval, value * rval)
       if (ul != (TYPE_UWORD) ul)
         werror (W_INT_OVL);
     }
-  else /* int */
+  else /* signed int */
     {
       TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
                      (TYPE_WORD) floatFromVal (rval);
@@ -1125,7 +1116,7 @@ valMult (value * lval, value * rval)
       if (l != (TYPE_WORD) l)
         werror (W_INT_OVL);
     }
-  return cheapestVal(val);
+  return cheapestVal (val);
 }
 
 /*------------------------------------------------------------------*/
@@ -1148,45 +1139,32 @@ valDiv (value * lval, value * rval)
   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
                           IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
   SPEC_SCLS (val->etype) = S_LITERAL;
-  /* both signed char and unsigned char are promoted to signed int */
-  if (IS_CHAR (lval->etype))
-    {
-      SPEC_USIGN (lval->etype) = 0;
-      SPEC_NOUN  (lval->etype) = V_INT;
-    }
-  if (IS_CHAR (rval->etype))
-    {
-      SPEC_USIGN (rval->etype) = 0;
-      SPEC_NOUN  (rval->etype) = V_INT;
-    }
-  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
+  SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
+                                                   rval->etype,
+                                                   TRUE));
 
   if (IS_FLOAT (val->type))
     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
+  else if (SPEC_LONG (val->type))
+    {
+      if (SPEC_USIGN (val->type))
+       SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
+         (TYPE_UDWORD) floatFromVal (rval);
+      else
+       SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
+         (TYPE_DWORD) floatFromVal (rval);
+    }
   else
     {
-      if (SPEC_LONG (val->type))
-       {
-         if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
-             (TYPE_UDWORD) floatFromVal (rval);
-         else
-           SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
-             (TYPE_DWORD) floatFromVal (rval);
-       }
+      if (SPEC_USIGN (val->type))
+        SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
+          (TYPE_UWORD) floatFromVal (rval);
       else
-       {
-         if (SPEC_USIGN (val->type)) {
-           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
-             (TYPE_UWORD) floatFromVal (rval);
-         } else {
-           SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
-             (TYPE_WORD) floatFromVal (rval);
-         }
-       }
+        SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
+          (TYPE_WORD) floatFromVal (rval);
     }
-  return cheapestVal(val);
+  return cheapestVal (val);
 }
 
 /*------------------------------------------------------------------*/
@@ -1202,8 +1180,10 @@ valMod (value * lval, value * rval)
   val->type = val->etype = newLink (SPECIFIER);
   SPEC_NOUN (val->type) = V_INT;       /* type is int */
   SPEC_SCLS (val->type) = S_LITERAL;   /* will remain literal */
-  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
+  SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
+                                                   rval->etype,
+                                                   TRUE));
 
   if (SPEC_LONG (val->type))
     {
@@ -1216,16 +1196,14 @@ valMod (value * lval, value * rval)
     }
   else
     {
-      if (SPEC_USIGN (val->type)) {
-       SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
-         (TYPE_UWORD) floatFromVal (rval);
-      } else {
-       SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
-         (TYPE_WORD) floatFromVal (rval);
-      }
+      if (SPEC_USIGN (val->type))
+        SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
+          (TYPE_UWORD) floatFromVal (rval);
+      else
+        SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
+          (TYPE_WORD) floatFromVal (rval);
     }
-
-  return cheapestVal(val);
+  return cheapestVal (val);
 }
 
 /*------------------------------------------------------------------*/
@@ -1243,43 +1221,30 @@ valPlus (value * lval, value * rval)
                           IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
   SPEC_SCLS  (val->type) = S_LITERAL;  /* will remain literal */
   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
-  /* both signed char and unsigned char are promoted to signed int */
-  if (IS_CHAR (lval->etype))
-    {
-      SPEC_USIGN (lval->etype) = 0;
-      SPEC_NOUN  (lval->etype) = V_INT;
-    }
-  if (IS_CHAR (rval->etype))
-    {
-      SPEC_USIGN (rval->etype) = 0;
-      SPEC_NOUN  (rval->etype) = V_INT;
-    }
-  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
+  SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
+                                                   rval->etype,
+                                                   TRUE));
   if (IS_FLOAT (val->type))
     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
+  else  if (SPEC_LONG (val->type))
+    {
+      if (SPEC_USIGN (val->type))
+        SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
+         (TYPE_UDWORD) floatFromVal (rval);
+      else
+        SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
+          (TYPE_DWORD) floatFromVal (rval);
+    }
   else
     {
-      if (SPEC_LONG (val->type))
-       {
-         if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
-             (TYPE_UDWORD) floatFromVal (rval);
-         else
-           SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
-             (TYPE_DWORD) floatFromVal (rval);
-       }
+      if (SPEC_USIGN (val->type))
+        SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
+          (TYPE_UWORD) floatFromVal (rval);
       else
-       {
-         if (SPEC_USIGN (val->type)) {
-           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
-             (TYPE_UWORD) floatFromVal (rval);
-         } else {
-           SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
-             (TYPE_WORD) floatFromVal (rval);
-         }
-       }
+        SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
+          (TYPE_WORD) floatFromVal (rval);
     }
-  return cheapestVal(val);
+  return cheapestVal (val);
 }
 
 /*------------------------------------------------------------------*/
@@ -1297,43 +1262,30 @@ valMinus (value * lval, value * rval)
                           IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
   SPEC_SCLS (val->type) = S_LITERAL;   /* will remain literal */
   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
-  /* both signed char and unsigned char are promoted to signed int */
-  if (IS_CHAR (lval->etype))
-    {
-      SPEC_USIGN (lval->etype) = 0;
-      SPEC_NOUN  (lval->etype) = V_INT;
-    }
-  if (IS_CHAR (rval->etype))
-    {
-      SPEC_USIGN (rval->etype) = 0;
-      SPEC_NOUN  (rval->etype) = V_INT;
-    }
-  SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
+  SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
+                                                   rval->etype,
+                                                   FALSE));
   if (IS_FLOAT (val->type))
     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
-  else
+  else  if (SPEC_LONG (val->type))
     {
-      if (SPEC_LONG (val->type))
-       {
-         if (SPEC_USIGN (val->type))
-           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
-             (TYPE_UDWORD) floatFromVal (rval);
-         else
-           SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
-             (TYPE_DWORD) floatFromVal (rval);
-       }
+      if (SPEC_USIGN (val->type))
+        SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
+          (TYPE_UDWORD) floatFromVal (rval);
       else
-       {
-         if (SPEC_USIGN (val->type)) {
-           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
-             (TYPE_UWORD) floatFromVal (rval);
-         } else {
-           SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
-             (TYPE_WORD) floatFromVal (rval);
-         }
-       }
+        SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
+          (TYPE_DWORD) floatFromVal (rval);
     }
-  return cheapestVal(val);
+  else
+   {
+     if (SPEC_USIGN (val->type))
+       SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
+         (TYPE_UWORD) floatFromVal (rval);
+     else
+       SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
+         (TYPE_WORD) floatFromVal (rval);
+    }
+  return cheapestVal (val);
 }
 
 /*------------------------------------------------------------------*/
@@ -1354,6 +1306,15 @@ valShift (value * lval, value * rval, int lr)
     SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype);
   SPEC_LONG (val->type) = SPEC_LONG (lval->etype);
 
+  if (getSize (lval->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
+       /* left shift */
+      (lr ||
+       /* right shift and unsigned */
+       (!lr && SPEC_USIGN (rval->type))))
+    {
+      werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
+    }
+
   if (SPEC_LONG (val->type))
     {
       if (SPEC_USIGN (val->type))
@@ -1384,7 +1345,7 @@ valShift (value * lval, value * rval, int lr)
            (TYPE_WORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
         }
     }
-  return cheapestVal(val);
+  return cheapestVal (val);
 }
 
 /*------------------------------------------------------------------*/
@@ -1433,17 +1394,18 @@ valCompare (value * lval, value * rval, int ctype)
          TYPE_UDWORD l, r;
 
          l = (TYPE_UDWORD) floatFromVal (lval);
-         if (SPEC_NOUN(lval->type) == V_CHAR)
-           l &= 0xffff; /* promote to int */
-         else if (!SPEC_LONG (lval->type))
-           l &= 0xffff;
-
          r = (TYPE_UDWORD) floatFromVal (rval);
-         if (SPEC_NOUN(rval->type) == V_CHAR)
-           r &= 0xffff; /* promote to int */
-         else if (!SPEC_LONG (rval->type))
-           r &= 0xffff;
-
+         /* In order to correctly compare 'signed int' and 'unsigned int' it's
+            neccessary to strip them to 16 bit.
+            Literals are reduced to their cheapest type, therefore left and
+            right might have different types. It's neccessary to find a
+            common type: int (used for char too) or long */
+         if (!IS_LONG (lval->etype) &&
+             !IS_LONG (rval->etype))
+           {
+             r = (TYPE_UWORD) r;
+             l = (TYPE_UWORD) l;
+           }
          SPEC_CVAL (val->type).v_int = l == r;
        }
       break;
@@ -1459,17 +1421,18 @@ valCompare (value * lval, value * rval, int ctype)
          TYPE_UDWORD l, r;
 
          l = (TYPE_UDWORD) floatFromVal (lval);
-         if (SPEC_NOUN(lval->type) == V_CHAR)
-           l &= 0xffff; /* promote to int */
-         else if (!SPEC_LONG (lval->type))
-           l &= 0xffff;
-
          r = (TYPE_UDWORD) floatFromVal (rval);
-         if (SPEC_NOUN(rval->type) == V_CHAR)
-           r &= 0xffff; /* promote to int */
-         else if (!SPEC_LONG (rval->type))
-           r &= 0xffff;
-
+         /* In order to correctly compare 'signed int' and 'unsigned int' it's
+            neccessary to strip them to 16 bit.
+            Literals are reduced to their cheapest type, therefore left and
+            right might have different types. It's neccessary to find a
+            common type: int (used for char too) or long */
+         if (!IS_LONG (lval->etype) &&
+             !IS_LONG (rval->etype))
+           {
+             r = (TYPE_UWORD) r;
+             l = (TYPE_UWORD) l;
+           }
          SPEC_CVAL (val->type).v_int = l != r;
        }
       break;
index 82abbb0f3fd9b6380ea23cef8f5c40a9c4048d0b..f413f7653370a6fb3b5f81689fc4e0d99d1cfa54 100644 (file)
@@ -434,7 +434,7 @@ leastUsedLR (set * sset)
 
     }
 
-  setToNull ((void **) &sset);
+  setToNull ((void *) &sset);
   sym->blockSpil = 0;
   return sym;
 }
index aaec505e3dd645825950506685aec836cadaa7d0..66767afe677bab280272cdc332f0ffcef583a812 100644 (file)
@@ -48,7 +48,7 @@ foo_mul (void)
 unsigned
 foo_div (void)
 {
-  return 33971 / i / 5 / i / i / 12;
+  return 33971u / i / 5 / i / i / 12;
 }
 
 unsigned
index e66585dd229a208d01bbbfd1e3e140d1fb7e6f64..08800c1471f39149401ca85a8cf48604b21cde72 100644 (file)
@@ -14,8 +14,6 @@
 typedef   signed {type} stype;
 typedef unsigned {type} utype;
 
-#define _{type}
-
 #if defined(PORT_HOST) || defined(SDCC_z80) || defined(SDCC_gbz80)
 #  define idata
 #  define code
@@ -23,9 +21,9 @@ typedef unsigned {type} utype;
 
 volatile char is8 = 8;
 
-signed char  sc;
-signed short ss;
-signed LONG  sl;
+  signed char  sc;
+  signed short ss;
+  signed LONG  sl;
 unsigned char  uc;
 unsigned short us;
 unsigned LONG  ul;
@@ -45,7 +43,33 @@ unsigned LONG t1, t2;
 void
 testOpOp(void)
 {
-  /* mul ast */
+  /* mul signedness: usualBinaryConversions() */
+  vsc = 0x7f;
+  vuc = 0xfe;
+
+  sc = vsc * vsc;
+  ASSERT(sc == 1);
+  sc = vuc * vsc;
+  ASSERT(sc == 2);
+  sc = vuc * vuc;
+  ASSERT(sc == 4);
+
+  ss = vsc * vsc;
+  ASSERT(ss == 0x3f01);
+  ss = vuc * vsc;
+  ASSERT(ss == 0x7e02);
+  ss = vuc * vuc;
+  ASSERT(ss == (short) 0xfc04);
+  /* after promotion the result of the multiplication is 'signed int', which overflows! */
+  if (sizeof (int) == 2)
+    ASSERT(vuc * vuc < 1);
+  else
+    {
+      vus = 0xfffe;
+      ASSERT(vus * vus < 1);
+    }
+
+  /* mul ast: valMult() */
   ASSERT((stype) -3 * (stype) -1 == (stype)  3);
   ASSERT((stype) -3 * (stype)  1 == (stype) -3);
   ASSERT((stype)  3 * (stype) -1 == (stype) -3);
@@ -77,11 +101,17 @@ testOpOp(void)
   ASSERT(1 *  40000  * is8 == 320000);                              /* LONG     */
   ASSERT(1 * 0x4000  * is8 == (sizeof(int) == 2 ? 0 : 0x20000));     /* unsigned */
 
-  ASSERT(-1 * 1  < 0);
-  ASSERT(-1 * 1u > 0);
-
-
-  /* mul icode */
+  ASSERT(-2 * 1  < 1); /* comparison with 0 is optimized, so let's use 1 instead */
+  ASSERT(-2 * 1u > 1);
+  ASSERT(0x7fffu     * 2  > 1);
+  ASSERT(0x7fffffffu * 2  > 1);
+  if (sizeof (int) == 2)
+    ASSERT(0x7fff * (unsigned char) 2 < 1);
+  else
+    ASSERT(0x7fffffff * (unsigned char) 2 < 1);
+  ASSERT(0x7fffffff  * (unsigned short) 2 < 1);
+
+  /* mul icode: operandOperation() */
   s = -3;
   ASSERT(s * (stype) -1 == (stype)  3);
   ASSERT(s * (stype)  1 == (stype) -3);
@@ -108,26 +138,85 @@ testOpOp(void)
   ASSERT((signed short) -2 * (unsigned short) 0x8004 == (sizeof(int) == 2 ? 0xfff8 : 0xfffefff8));
   ASSERT((signed LONG ) -2 * (unsigned LONG ) 0x8004 == 0xfffefff8);
 
-
-
+  /* div ast: valDiv() */
   ASSERT((stype) -12 / (stype) -3 == (stype)  4);
   ASSERT((stype) -12 / (stype)  3 == (stype) -4);
   ASSERT((stype)  12 / (stype) -3 == (stype) -4);
 
-//  ASSERT((stype) -12 / (utype) -3 == (stype)  4);
-//  ASSERT((utype) -12 / (stype) -3 == (stype)  4);
-//  ASSERT((utype) -12 / (utype) -3 == (stype)  4);
+  ASSERT((unsigned char ) -12 / (signed char ) -3 == (sizeof(int) == 2 ? 0xffaf : 0xffffffaf));
+  ASSERT((unsigned short) -12 / (signed short) -3 == (sizeof(int) == 2 ?      0 : 0xffffaaaf));
+  ASSERT((unsigned LONG ) -12 / (signed LONG ) -3 == 0);
+  ASSERT((utype)          -12 / (stype)         3 == (stype) 0x55555551);
+  ASSERT((unsigned char )  12 / (signed char ) -3 == -4);
+  ASSERT((unsigned short)  12 / (signed short) -3 == (sizeof(int) == 2 ?      0 : 0xfffffffc));
+  ASSERT((unsigned LONG )  12 / (signed LONG ) -3 == 0);
 
+  ASSERT((stype)        -12 / (utype)          -3 == 0);
+  ASSERT((signed char ) -12 / (unsigned char )  3 == -4);
+  ASSERT((signed short) -12 / (unsigned short)  3 == (sizeof(int) == 2 ? 0x5551 :  -4));
+  ASSERT((signed LONG ) -12 / (unsigned LONG )  3 == 0x55555551);
+  ASSERT((stype)         12 / (utype)          -3 == 0);
 
   ASSERT(12u / 3 * 10000 == 40000);
 
   ASSERT(-1 / 1 < 0);
 
+  /* div icode: operandOperation() */
+  s = -12;
+  ASSERT(s / (stype) -3 == (stype)  4);
+  s = -12;
+  ASSERT(s / (stype)  3 == (stype) -4);
+  s = 12;
+  ASSERT(s / (stype) -3 == (stype) -4);
+
+  uc = -12;
+  ASSERT(uc / (signed char ) -3 == (sizeof(int) == 2 ? 0xffaf : 0xffffffaf));
+  us = -12;
+  ASSERT(us / (signed short) -3 == (sizeof(int) == 2 ?      0 : 0xffffaaaf));
+  ul = -12;
+  ASSERT(ul / (signed LONG ) -3 == 0);
+  u  = -12;
+  ASSERT(u  / (stype)         3 == (stype) 0x55555551);
+  uc = 12;
+  ASSERT(uc / (signed char ) -3 == -4);
+  us = 12;
+  ASSERT(us / (signed short) -3 == (sizeof(int) == 2 ?      0 : 0xfffffffc));
+  ul = 12;
+  ASSERT(ul / (signed LONG ) -3 == 0);
+
+  s  = -12;
+  ASSERT(s  / (utype)          -3 == 0);
+  sc = -12;
+  ASSERT(sc / (unsigned char )  3 == -4);
+  ss = -12;
+  ASSERT(ss / (unsigned short)  3 == (sizeof(int) == 2 ? 0x5551 :  -4));
+  sl = -12;
+  ASSERT(sl / (unsigned LONG )  3 == 0x55555551);
+  s  = 12;
+  ASSERT(s  / (utype)          -3 == 0);
+
+
+  /* mod ast: valMod() */
+  /* -11 : 0xfff5 */
+  /* -17 : 0xffef */
+  ASSERT((stype) -17 % (stype) -11 == (stype) -6);
+  ASSERT((stype) -17 % (stype)  11 == (stype) -6);
+  ASSERT((stype)  17 % (stype) -11 == (stype)  6);
+  ASSERT((unsigned char ) -17 % (signed char ) -11 ==   8);
+  ASSERT((unsigned short) -17 % (signed short) -11 == (sizeof(int) == 2 ? -17 : 3));
+  ASSERT((unsigned LONG ) -17 % (signed LONG ) -11 == -17);
+  ASSERT((unsigned char ) -17 % (signed char )  11 ==   8);
+  ASSERT((unsigned short) -17 % (signed short)  11 ==   3);
+  ASSERT((unsigned LONG ) -17 % (signed LONG )  11 ==   9);
+  ASSERT((unsigned char )  17 % (signed char ) -11 ==   6);
+  ASSERT((unsigned short)  17 % (signed short) -11 == (sizeof(int) == 2 ? 17 : 6));
+  ASSERT((unsigned LONG )  17 % (signed LONG ) -11 ==  17);
 
+  ASSERT(-3 % 2 < 0);
 
-  ASSERT((stype) -14 % (stype) -3 == (stype) -2);
-  ASSERT((stype) -14 % (stype)  3 == (stype) -2);
-  ASSERT((stype)  14 % (stype) -3 == (stype)  2);
 
-  ASSERT(-3 % 2 < 0);
+  /* add */
+  ASSERT( 80  +  80  == 160);
+  ASSERT(150  + 150  == 300);
+  ASSERT(160u + 160u == 320);
 }