src/SDCCval.c (valMinus): fixed bug #826041
[fw/sdcc] / src / SDCCval.c
index 0bdace5e2ccbf0bc9d914cb1f8e22bf0a27c7396..8aa1e3b97bc1ca596b5b2165b6ba70f194f3909d 100644 (file)
@@ -1113,8 +1113,7 @@ valMult (value * lval, value * rval)
                        (TYPE_UWORD) floatFromVal (rval);
 
       SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
-      if (!options.lessPedantic &&
-          ul != (TYPE_UWORD) ul)
+      if (ul != (TYPE_UWORD) ul)
         werror (W_INT_OVL);
     }
   else /* int */
@@ -1123,8 +1122,7 @@ valMult (value * lval, value * rval)
                      (TYPE_WORD) floatFromVal (rval);
 
       SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
-      if (!options.lessPedantic &&
-          l != (TYPE_WORD) l)
+      if (l != (TYPE_WORD) l)
         werror (W_INT_OVL);
     }
   return cheapestVal(val);
@@ -1243,27 +1241,30 @@ valPlus (value * lval, value * rval)
   val->type = val->etype = newLink (SPECIFIER);
   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
                           IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
-  SPEC_SCLS (val->type) = S_LITERAL;   /* will remain literal */
-  SPEC_USIGN (val->type) =
-    SPEC_USIGN (lval->etype) &&
-    SPEC_USIGN (rval->etype) &&
-    (floatFromVal(lval)+floatFromVal(rval))>=0;
-
-  SPEC_LONG (val->type) = 1;
-
+  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));
   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 = (unsigned long) floatFromVal (lval) +
-             (unsigned long) floatFromVal (rval);
-         else
-           SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
-             (long) floatFromVal (rval);
-       }
+      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);
     }
   return cheapestVal(val);
 }
@@ -1282,38 +1283,29 @@ valMinus (value * lval, value * rval)
   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
                           IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
   SPEC_SCLS (val->type) = S_LITERAL;   /* will remain literal */
-  SPEC_USIGN (val->type) = 
-    SPEC_USIGN (lval->etype) &&
-    SPEC_USIGN (rval->etype) &&
-    (floatFromVal(lval)-floatFromVal(rval))>=0;
-
-  SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
-
+  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));
   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 = 
-             (unsigned long) floatFromVal (lval) -
-             (unsigned long) floatFromVal (rval);
-         } else {
-           SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
-             (long) 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 = (unsigned) floatFromVal (lval) -
-             (unsigned) floatFromVal (rval);
-         } else {
-           SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - 
-             (int) floatFromVal (rval);
-         }
-       }
+       SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
+         (TYPE_DWORD) floatFromVal (rval);
     }
   return cheapestVal(val);
 }
@@ -1339,14 +1331,14 @@ valShift (value * lval, value * rval, int lr)
   if (SPEC_USIGN (val->type))
     {
       SPEC_CVAL (val->type).v_ulong = lr ?
-       (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
-       (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
+       (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
+       (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
     }
   else
     {
       SPEC_CVAL (val->type).v_long = lr ?
-       (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
-       (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
+       (TYPE_DWORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
+       (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
     }
   return cheapestVal(val);
 }