Operators <<, >>, are now fully working for constant shifts on unsigned char and...
[fw/sdcc] / src / SDCCicode.c
index 628a1dba9c3664040a13ccbf0c22066d14d00c39..5755fc38557d06ba07b0db25117ee26e7cd08394 100644 (file)
@@ -131,11 +131,12 @@ iCodeTable codeTable[] =
      pedantic>1: "char c=200" is not allowed (evaluates to -56)
 */
 
-void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) {
+void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
   LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
   char message[132]="";
   int warnings=0;
   int negative=0;
+  long v=SPEC_CVAL(val->type).v_long;
 
 #if 0
   // this could be a good idea
@@ -148,10 +149,9 @@ void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) {
     return;
   }
 
-  if (v<0) {
+  if (!SPEC_USIGN(val->type) && v<0) {
     negative=1;
-    // if not pedantic: -1 equals to 0xf..f
-    if (SPEC_USIGN(ltype) && (!pedantic ? v!=-1 : 1)) {
+    if (SPEC_USIGN(ltype) && (pedantic>1)) {
       warnings++;
     }
     v=-v;
@@ -1578,6 +1578,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
   sym_link *optype;
   sym_link *opetype = getSpec (optype = operandType (op));
   sym_link *restype;
+  int errors=0;
 
   /* one of them has size zero then error */
   if (IS_VOID (optype))
@@ -1595,31 +1596,44 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
     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)) { // from a non pointer
+    if (!IS_PTR(optype) && !IS_FUNC(optype)) { // from a non pointer
       if (IS_INTEGRAL(optype)) { 
        // maybe this is NULL, than it's ok.
        if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
-         if (IS_GENPTR(type)) {
+         if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
            // no way to set the storage
            if (IS_LITERAL(optype)) {
              werror(E_LITERAL_GENERIC);
+             errors++;
            } else {
              werror(E_NONPTR2_GENPTR);
+             errors++;
            }
          } else if (implicit) {
            werror(W_INTEGRAL2PTR_NOCAST);
+           errors++;
          }
        }
-      }        else { // shouldn't do that with float, array or structure
-       werror(E_INCOMPAT_TYPES);
+      }        else { 
+       // shouldn't do that with float, array or structure unless to void
+       if (!IS_VOID(getSpec(type)) && 
+           !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
+         werror(E_INCOMPAT_TYPES);
+         errors++;
+       }
       }
     } else { // from a pointer to a pointer
-      if (implicit) { // if not to generic, they have to match 
-       if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
-         werror(E_INCOMPAT_PTYPES);
+      if (!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 ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
+             werror(E_INCOMPAT_PTYPES);
+             errors++;
+           }
+         }
        }
       }
     }
@@ -1628,12 +1642,23 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
       if (implicit) { // sneaky
        if (IS_INTEGRAL(type)) {
          werror(W_PTR2INTEGRAL_NOCAST);
+         errors++;
        } else { // shouldn't do that with float, array or structure
          werror(E_INCOMPAT_TYPES);
+         errors++;
        }
       }
     }
   }
+  if (errors) {
+    /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
+       implicit?"(implicit)":"", errors); */
+    fprintf (stderr, "from type '");
+    printTypeChain (optype, stderr);
+    fprintf (stderr, "' to type '");
+    printTypeChain (type, stderr);
+    fprintf (stderr, "'\n");
+  }
 
   /* if they are the same size create an assignment */
   if (getSize (type) == getSize (optype) &&
@@ -2485,7 +2510,7 @@ geniCodeLogic (operand * left, operand * right, int op)
   if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
     {
       checkConstantRange(ltype, 
-                        operandLitValue(right), "compare operation", 1);
+                        OP_VALUE(right), "compare operation", 1);
     }
 
   ctype = usualBinaryConversions (&left, &right);
@@ -2578,7 +2603,7 @@ geniCodeAssign (operand * left, operand * right, int nosupdate)
   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
     {
       checkConstantRange(ltype, 
-                        operandLitValue(right), "= operation", 0);
+                        OP_VALUE(right), "= operation", 0);
     }
 
   /* if the left & right type don't exactly match */
@@ -3273,8 +3298,9 @@ ast2iCode (ast * tree,int lvl)
 
     case '[':                  /* array operation */
       {
-       sym_link *ltype = operandType (left);
-       left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+       //sym_link *ltype = operandType (left);
+       //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+       left = geniCodeRValue (left, FALSE);
        right = geniCodeRValue (right, TRUE);
       }