Fixed bug #621531 (const & volatile confusion in the type chain).
[fw/sdcc] / src / SDCCicode.c
index abafe41ffb64f990d03481a4fce45809f17597a7..44dddc1175750e87adfba60a77b369db35302d45 100644 (file)
@@ -1097,9 +1097,9 @@ operandOperation (operand * left, operand * right,
                  ul != (TYPE_UWORD) ul)
                werror (W_INT_OVL);
            }
-         else /* int */
+         else /* signed int */
            {
-             /* int is handled here in order to detect overflow */
+             /* signed int is handled here in order to detect overflow */
              TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
                             (TYPE_WORD) operandLitValue (right);
 
@@ -1470,7 +1470,7 @@ operandFromSymbol (symbol * sym)
       ok &&                    /* farspace check */
       !IS_BITVAR (sym->etype)  /* not a bit variable */
     )
-    {
+    {                                   
 
       /* we will use it after all optimizations
          and before liveRange calculation */
@@ -1989,8 +1989,8 @@ geniCodeDivision (operand * left, operand * right)
 
   resType = usualBinaryConversions (&left, &right);
 
-  /* if the right is a literal & power of 2 
-     and left is unsigned then make it a    
+  /* 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) &&
@@ -2198,19 +2198,8 @@ aggrToPtr (sym_link * type, bool force)
 
   ptype->next = type;
 
-  /* if the output class is code */
-  if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
-    DCL_PTR_CONST (ptype) = port->mem.code_ro;
-
-  /* if the variable was declared a constant */
-  /* then the pointer points to a constant */
-  if (IS_CONSTANT (etype))
-    DCL_PTR_CONST (ptype) = 1;
-
-  /* the variable was volatile then pointer to volatile */
-  if (IS_VOLATILE (etype))
-    DCL_PTR_VOLATILE (ptype) = 1;
-
+  /* set the pointer depending on the storage class */
+  DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
   return ptype;
 }
 
@@ -2224,17 +2213,7 @@ geniCodeArray2Ptr (operand * op)
   sym_link *opetype = getSpec (optype);
 
   /* set the pointer depending on the storage class */
-  if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
-    DCL_PTR_CONST (optype) = port->mem.code_ro;
-
-  /* if the variable was declared a constant */
-  /* then the pointer points to a constant */
-  if (IS_CONSTANT (opetype))
-    DCL_PTR_CONST (optype) = 1;
-
-  /* the variable was volatile then pointer to volatile */
-  if (IS_VOLATILE (opetype))
-    DCL_PTR_VOLATILE (optype) = 1;
+  DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
 
   op->isaddr = 0;
   return op;
@@ -2309,7 +2288,7 @@ geniCodeStruct (operand * left, operand * right, bool islval)
   retype = getSpec (operandType (IC_RESULT (ic)));
   SPEC_SCLS (retype) = SPEC_SCLS (etype);
   SPEC_OCLS (retype) = SPEC_OCLS (etype);
-  SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
+  SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype); /* EEP - I'm doubtful about this */
 
   if (IS_PTR (element->type))
     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
@@ -2522,15 +2501,7 @@ geniCodeAddressOf (operand * op)
   p = newLink (DECLARATOR);
 
   /* set the pointer depending on the storage class */
-  if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
-    DCL_PTR_CONST (p) = port->mem.code_ro;
-
-  /* make sure we preserve the const & volatile */
-  if (IS_CONSTANT (opetype))
-    DCL_PTR_CONST (p) = 1;
-
-  if (IS_VOLATILE (opetype))
-    DCL_PTR_VOLATILE (p) = 1;
+  DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
 
   p->next = copyLinkChain (optype);
 
@@ -2630,11 +2601,6 @@ geniCodeDerefPtr (operand * op,int lvl)
 
   op->isGptr = IS_GENPTR (optype);
 
-  /* if the pointer was declared as a constant */
-  /* then we cannot allow assignment to the derefed */
-  if (IS_PTR_CONST (optype))
-    SPEC_CONST (retype) = 1;
-
   op->isaddr = (IS_PTR (rtype) ||
                IS_STRUCT (rtype) ||
                IS_INT (rtype) ||
@@ -2714,6 +2680,49 @@ geniCodeLogic (operand * left, operand * right, int op)
                         OP_VALUE(right), "compare operation", 1);
     }
 
+  /* if one operand is a pointer and the other is a literal generic void pointer,
+     change the type of the literal generic void pointer to match the other pointer */
+  if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
+      && IS_PTR (rtype) && !IS_GENPTR(rtype))
+    {
+      /* find left's definition */
+      ic = (iCode *) setFirstItem (iCodeChain);
+      while (ic)
+        {
+          if (((ic->op == CAST) || (ic->op == '='))
+              && isOperandEqual(left, IC_RESULT (ic)))
+            break;
+          else
+            ic = setNextItem (iCodeChain);
+        }
+      /* if casting literal to generic pointer, then cast to rtype instead */
+      if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
+        {
+          left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
+          ltype = operandType(left);
+        }
+    }
+  if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
+      && IS_PTR (ltype) && !IS_GENPTR(ltype))
+    {
+      /* find right's definition */
+      ic = (iCode *) setFirstItem (iCodeChain);
+      while (ic)
+        {
+          if (((ic->op == CAST) || (ic->op == '='))
+              && isOperandEqual(right, IC_RESULT (ic)))
+            break;
+          else
+            ic = setNextItem (iCodeChain);
+        }
+      /* if casting literal to generic pointer, then cast to rtype instead */
+      if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic))) 
+        {
+          right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
+          rtype = operandType(right);
+        }
+    }
+
   ctype = usualBinaryConversions (&left, &right);
 
   ic = newiCode (op, left, right);
@@ -3656,9 +3665,21 @@ ast2iCode (ast * tree,int lvl)
     case NE_OP:
     case AND_OP:
     case OR_OP:
+      /* different compilers (even different gccs) evaluate
+        the two calls in a different order. to get the same
+        result on all machines we've to specify a clear sequence.
       return geniCodeLogic (geniCodeRValue (left, FALSE),
-                           geniCodeRValue (right, FALSE),
-                           tree->opval.op);
+                            geniCodeRValue (right, FALSE),
+                            tree->opval.op);
+      */
+      {
+       operand *leftOp, *rightOp;
+
+       rightOp = geniCodeRValue (right, FALSE);
+       leftOp  = geniCodeRValue (left , FALSE);
+
+       return geniCodeLogic (leftOp, rightOp, tree->opval.op);
+      }
     case '?':
       return geniCodeConditional (tree,lvl);