* src/SDCCval.c (checkConstantRange): added
[fw/sdcc] / src / SDCCicode.c
index e24cc39564a7fd32665db75ce2bdd0255ad71083..30af1cd43f1c7745d73dd45834fe179ad73b9618 100644 (file)
@@ -127,88 +127,6 @@ iCodeTable codeTable[] =
   {SWAP, "swap", picGenericOne, NULL}
 };
 
-/*-----------------------------------------------------------------*/
-/* checkConstantRange: check a constant against the type           */
-/*-----------------------------------------------------------------*/
-
-
-/*   pedantic=0: allmost anything is allowed as long as the absolute
-       value is within the bit range of the type, and -1 is treated as
-       0xf..f for unsigned types (e.g. in assign)
-     pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
-     pedantic>1: "char c=200" is not allowed (evaluates to -56)
-*/
-
-void checkConstantRange(sym_link *ltype, value *val, char *msg,
-                        int pedantic) {
-  double max;
-  int warnings=0;
-  int negative=0;
-  long v;
-
-  max = pow ((double)2.0, (double)bitsForType(ltype));
-
-  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 (IS_UNSIGNED(val->type)) {
-      v=SPEC_CVAL(val->type).v_uint;
-    } else {
-      v=SPEC_CVAL(val->type).v_int;
-    }
-  }
-
-
-#if 0
-  // this could be a good idea
-  if (options.pedantic)
-    pedantic=2;
-#endif
-
-  if (IS_FLOAT(ltype)) {
-    // anything will do
-    return;
-  }
-
-  if (IS_FIXED(ltype)) {
-    // anything will do
-    return;
-  }
-
-  if (!IS_UNSIGNED(val->type) && v<0) {
-    negative=1;
-    if (IS_UNSIGNED(ltype) && (pedantic>1)) {
-      warnings++;
-    }
-    v=-v;
-  }
-
-  // if very pedantic: "char c=200" is not allowed
-  if (pedantic>1 && !IS_UNSIGNED(ltype)) {
-    max = max/2 + negative;
-  }
-
-  if (v >= max) {
-    warnings++;
-  }
-
-#if 0 // temporary disabled, leaving the warning as a reminder
-  if (warnings) {
-    SNPRINTF (message, sizeof(message), "for %s %s in %s",
-             IS_UNSIGNED(ltype) ? "unsigned" : "signed",
-             nounName(ltype), msg);
-    werror (W_CONST_RANGE, message);
-
-    if (pedantic>1)
-      fatalError++;
-  }
-#endif
-}
-
 /*-----------------------------------------------------------------*/
 /* operandName - returns the name of the operand                   */
 /*-----------------------------------------------------------------*/
@@ -1839,7 +1757,7 @@ setOperandType (operand * op, sym_link * type)
 /*-----------------------------------------------------------------*/
 /* Get size in byte of ptr need to access an array                 */
 /*-----------------------------------------------------------------*/
-static int
+static unsigned int
 getArraySizePtr (operand * op)
 {
   sym_link *ltype = operandType(op);
@@ -2410,11 +2328,7 @@ geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
           size  = operandFromLit (getSize (ltype->next));
           SPEC_USIGN (getSpec (operandType (size))) = 1;
           indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-          right = geniCodeMultiply (right,
-                                    size,
-                                    (getArraySizePtr(left) >= INTSIZE) ?
-                                      RESULT_TYPE_INT :
-                                      RESULT_TYPE_CHAR);
+          right = geniCodeMultiply (right, size, resultType);
           /* 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: */
@@ -2513,6 +2427,14 @@ geniCodeArray (operand * left, operand * right, int lvl)
   operand *size;
   sym_link *ltype = operandType (left);
   bool indexUnsigned;
+  RESULT_TYPE resultType;
+
+  resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
+  if (DCL_ELEM (ltype))
+    {
+      if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
+        resultType = RESULT_TYPE_CHAR;
+    }
 
   if (IS_PTR (ltype))
     {
@@ -2521,22 +2443,13 @@ geniCodeArray (operand * left, operand * right, int lvl)
           left = geniCodeRValue (left, FALSE);
         }
 
-      return geniCodeDerefPtr (geniCodeAdd (left,
-                                            right,
-                                            (getArraySizePtr(left) >= INTSIZE) ?
-                                              RESULT_TYPE_INT :
-                                              RESULT_TYPE_CHAR,
-                                            lvl),
+      return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
                                lvl);
     }
   size = operandFromLit (getSize (ltype->next));
   SPEC_USIGN (getSpec (operandType (size))) = 1;
   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-  right = geniCodeMultiply (right,
-                            size,
-                            (getArraySizePtr(left) >= INTSIZE) ?
-                              RESULT_TYPE_INT :
-                              RESULT_TYPE_CHAR);
+  right = geniCodeMultiply (right, size, resultType);
   /* 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)
@@ -2848,7 +2761,7 @@ geniCodeAddressOf (operand * op)
       return op;
     }
 
-  /* other wise make this of the type coming in */
+  /* otherwise make this of the type coming in */
   ic = newiCode (ADDRESS_OF, op, NULL);
   IC_RESULT (ic) = newiTempOperand (p, 1);
   IC_RESULT (ic)->isaddr = 0;
@@ -3015,8 +2928,17 @@ geniCodeLogic (operand * left, operand * right, int op)
      check if the literal value is within bounds */
   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
     {
-      checkConstantRange(ltype,
-                         OP_VALUE(right), "compare operation", 1);
+      CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
+      switch (ccr_result)
+        {
+          case CCR_ALWAYS_TRUE:
+          case CCR_ALWAYS_FALSE:
+            if (!options.lessPedantic)
+              werror (W_COMP_RANGE, "true resp. false");
+            return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
+          default:
+            break;
+        }
     }
 
   /* if one operand is a pointer and the other is a literal generic void pointer,
@@ -3062,7 +2984,7 @@ geniCodeLogic (operand * left, operand * right, int op)
         }
     }
 
-  ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
+  ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
 
   ic = newiCode (op, left, right);
   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
@@ -3233,10 +3155,11 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
 
   /* left is integral type and right is literal then
      check if the literal value is within bounds */
-  if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
+  if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
+      checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
+      !options.lessPedantic)
     {
-      checkConstantRange(ltype,
-                         OP_VALUE(right), "= operation", 0);
+      werror (W_LIT_OVERFLOW);
     }
 
   /* if the left & right type don't exactly match */