* src/SDCCast.c (decorateType): fix for RFE 1475742, optimize 'ifx (op == 0)' resp...
[fw/sdcc] / src / SDCCast.c
index 285bf5e9b8d5d76f15fbe8474eacdd16cc60820d..66452408a22bd8a0763695d22b88918b499262ae 100644 (file)
@@ -1467,8 +1467,11 @@ constExprValue (ast * cexpr, int check)
     }
 
   /* return the value */
-  return cexpr->opval.val;
-
+  if (IS_AST_VALUE (cexpr))
+    {
+      return cexpr->opval.val;
+    }
+   return NULL;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2239,7 +2242,7 @@ getLeftResultType (ast *tree, RESULT_TYPE resultType)
       case '[':
         if (!IS_ARRAY (LTYPE (tree)))
           return resultType;
-        if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
+        if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
           return RESULT_TYPE_CHAR;
         return resultType;
       default:
@@ -2250,7 +2253,7 @@ getLeftResultType (ast *tree, RESULT_TYPE resultType)
 /*--------------------------------------------------------------------*/
 /* decorateType - compute type for this tree, also does type checking.*/
 /* This is done bottom up, since type has to flow upwards.            */
-/* resultType flows top-down and forces e.g. char-arithmetik, if the  */
+/* resultType flows top-down and forces e.g. char-arithmetic, if the  */
 /* result is a char and the operand(s) are int's.                     */
 /* It also does constant folding, and parameter checking.             */
 /*--------------------------------------------------------------------*/
@@ -3626,6 +3629,13 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       changePointer(LTYPE(tree));
       checkTypeSanity(LETYPE(tree), "(cast)");
 
+      /* if 'from' and 'to' are the same remove the superflous cast, */
+      /* this helps other optimizations */
+      if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
+        {
+          return tree->right;
+        }
+
       /* If code memory is read only, then pointers to code memory */
       /* implicitly point to constants -- make this explicit       */
       {
@@ -3913,6 +3923,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                 goto errorTreeReturn;
               }
         }
+
       /* if unsigned value < 0  then always false */
       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
       if (SPEC_USIGN(LETYPE(tree)) &&
@@ -3940,9 +3951,23 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                                      tree->right); /* val 0 */
               tree->right->lineno = tree->lineno;
               tree->right->left->lineno = tree->lineno;
-              decorateType (tree->right, RESULT_TYPE_NONE);
+              tree->decorated = 0;
+              return decorateType (tree, resultType);
             }
         }
+
+      /* 'ifx (op == 0)' -> 'ifx (!(op))' */
+      if (IS_LITERAL(RTYPE(tree))  &&
+          floatFromVal (valFromType (RETYPE (tree))) == 0 &&
+          tree->opval.op == EQ_OP &&
+          resultType == RESULT_TYPE_IFX)
+        {
+          tree->opval.op = '!';
+          tree->right = NULL;
+          tree->decorated = 0;
+          return decorateType (tree, resultType);
+        }
+
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) &&
@@ -3989,7 +4014,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      TTYPE (tree) = TETYPE (tree) = newCharLink ();
+      TTYPE (tree) = TETYPE (tree) = newBoolLink ();
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -4348,7 +4373,10 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           parmNumber = 1;
 
           if (IS_FUNCPTR (LTYPE (tree)))
-            functype = LTYPE (tree)->next;
+            {
+              functype = LTYPE (tree)->next;
+              processFuncPtrArgs (functype);
+            }
           else
             functype = LTYPE (tree);
 
@@ -4519,7 +4547,6 @@ sizeofOp (sym_link * type)
 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
-#define IS_NULLOP(ex) (ex->type == EX_OP && ex->opval.op == NULLOP)
 
 /*-----------------------------------------------------------------*/
 /* backPatchLabels - change and or not operators to flow control    */
@@ -5218,12 +5245,12 @@ optimizeRRCRLC (ast * root)
      into a RRC operation
      note : by 7 I mean (number of bits required to hold the
      variable -1 ) */
-  /* if the root operations is not a | operation the not */
+  /* if the root operation is not a | operation then not */
   if (!IS_BITOR (root))
     return root;
 
   /* I have to think of a better way to match patterns this sucks */
-  /* that aside let start looking for the first case : I use a the
+  /* that aside let's start looking for the first case : I use a
      negative check a lot to improve the efficiency */
   /* (?expr << 1) | (?expr >> 7) */
   if (IS_LEFT_OP (root->left) &&
@@ -5381,7 +5408,7 @@ optimizeSWAP (ast * root)
      into a SWAP : operation ..
      note : by 4 I mean (number of bits required to hold the
      variable /2 ) */
-  /* if the root operations is not a | operation the not */
+  /* if the root operation is not a | operation then not */
   if (!IS_BITOR (root))
     return root;