* src/SDCCicode.c (geniCodeArray): applied patch from Stas Sergeev proposed in FR...
[fw/sdcc] / src / SDCCicode.c
index a3f26e677ac067660253f6058407c220b533bab9..48cc6eabca252a2b42a071114759de04c8582bce 100644 (file)
@@ -1202,8 +1202,9 @@ operandOperation (operand * left, operand * right,
     case LEFT_OP:
       /* The number of left shifts is always unsigned. Signed doesn't make
         sense here. Shifting by a negative number is impossible. */
-      retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
-                              (TYPE_UDWORD) operandLitValue (right));
+      retval = operandFromValue (valCastLiteral (type,
+                                ((TYPE_UDWORD) operandLitValue (left) <<
+                                 (TYPE_UDWORD) operandLitValue (right))));
       break;
     case RIGHT_OP:
       /* The number of right shifts is always unsigned. Signed doesn't make
@@ -1763,12 +1764,19 @@ usualBinaryConversions (operand ** op1, operand ** op2,
      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;
+    {
+      sym_link *retype = getSpec (rtype);
+      sym_link *letype = getSpec (ltype);
 
+      if (   IS_CHAR (letype)
+         && IS_CHAR (retype)
+         && IS_UNSIGNED (letype)
+         && IS_UNSIGNED (retype))
+       {
+         return ctype;
+       }
+    }
   *op1 = geniCodeCast (ctype, *op1, TRUE);
   *op2 = geniCodeCast (ctype, *op2, TRUE);
 
@@ -2215,6 +2223,7 @@ geniCodeAdd (operand * left, operand * right, int lvl)
       if (getSize (ltype->next) != 1)
         {
          size  = operandFromLit (getSize (ltype->next));
+         SPEC_USIGN (getSpec (operandType (size))) = 1;
          indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
          right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
          /* Even if right is a 'unsigned char',
@@ -2298,6 +2307,7 @@ operand *
 geniCodeArray (operand * left, operand * right,int lvl)
 {
   iCode *ic;
+  operand *size;
   sym_link *ltype = operandType (left);
   bool indexUnsigned;
 
@@ -2310,9 +2320,10 @@ geniCodeArray (operand * left, operand * right,int lvl)
 
       return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
     }
+  size = operandFromLit (getSize (ltype->next));
+  SPEC_USIGN (getSpec (operandType (size))) = 1;
   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-  right = geniCodeMultiply (right,
-                           operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
+  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)
@@ -3777,7 +3788,7 @@ ast2iCode (ast * tree,int lvl)
        return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
 
     case '-':
-      if (right) 
+      if (right)
        return geniCodeSubtract (geniCodeRValue (left, FALSE),
                                 geniCodeRValue (right, FALSE));
       else