1) SDCCast.c - allow cast of ZERO to generic pointer (Special case for NULL)
[fw/sdcc] / src / SDCCast.c
index 5607e136faf83037aa25a9fcfdd4da7eda113534..1fcc17975a1df5678152ca1b6d71a8d09b47f030 100644 (file)
@@ -610,6 +610,7 @@ processParms (ast * func,
              int *parmNumber,
              bool rightmost)
 {
+  int castError=0;
   sym_link *fetype = func->etype;
 
   /* if none of them exist */
@@ -629,7 +630,7 @@ processParms (ast * func,
   /* have parameters                                   */
   if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
     {
-      werror (E_NONRENT_ARGS);
+      werror (W_NONRENT_ARGS);
       return 1;
     }
 
@@ -743,17 +744,45 @@ processParms (ast * func,
        }
     }
 
+
   /* the parameter type must be at least castable */
   if (compareType (defParm->type, actParm->ftype) == 0)
     {
-      werror (E_TYPE_MISMATCH_PARM, *parmNumber);
-      werror (E_CONTINUE, "defined type ");
-      printTypeChain (defParm->type, stderr);
-      fprintf (stderr, "\n");
-      werror (E_CONTINUE, "actual type ");
-      printTypeChain (actParm->ftype, stderr);
-      fprintf (stderr, "\n");
+      castError++;
+    }
+
+#ifdef JWK20010916
+  if (!IS_SPEC(defParm->type) && !IS_SPEC(actParm->ftype)) {
+    // now we have two pointers, check if they point to the same
+    sym_link *dtype=defParm->type, *atype=actParm->ftype;
+    do {
+      dtype=dtype->next;
+      atype=atype->next;
+      if (
+         (dtype->next && !atype->next) ||
+         (!dtype->next && atype->next) ||
+         compareType (dtype, atype)!=1) {
+       castError++;
+      }
+    } while (dtype->next && atype->next);
+    if (IS_SPEC(dtype) && IS_SPEC(atype)) {
+      // ok so far, we have two etypes, they must have the same SCLASS
+      if (SPEC_SCLS(dtype)!=SPEC_SCLS(atype)) {
+       castError++;
+      }
     }
+  }
+#endif
+
+  if (castError) {
+    werror (W_INCOMPAT_CAST);
+    fprintf (stderr, "type --> '");
+    printTypeChain (actParm->ftype, stderr);
+    fprintf (stderr, "' ");
+    fprintf (stderr, "assigned to type --> '");
+    printTypeChain (defParm->type, stderr);
+    fprintf (stderr, "'\n");
+  }
 
   /* if the parameter is castable then add the cast */
   if (compareType (defParm->type, actParm->ftype) < 0)
@@ -1990,10 +2019,10 @@ decorateType (ast * tree)
 
   switch (tree->opval.op)
     {
-/*------------------------------------------------------------------*/
-/*----------------------------*/
-      /*        array node          */
-/*----------------------------*/
+           /*------------------------------------------------------------------*/
+           /*----------------------------*/
+           /*        array node          */
+           /*----------------------------*/
     case '[':
 
       /* determine which is the array & which the index */
@@ -2032,10 +2061,10 @@ decorateType (ast * tree)
       }
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      struct/union          */
-/*----------------------------*/
+      /*----------------------------*/
     case '.':
       /* if this is not a structure */
       if (!IS_STRUCT (LTYPE (tree)))
@@ -2049,10 +2078,10 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*    struct/union pointer    */
-/*----------------------------*/
+      /*----------------------------*/
     case PTR_OP:
       /* if not pointer to a structure */
       if (!IS_PTR (LTYPE (tree)))
@@ -2104,7 +2133,7 @@ decorateType (ast * tree)
          if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
            {
              werror (E_BITWISE_OP);
-             werror (E_CONTINUE, "left & right types are ");
+             werror (W_CONTINUE, "left & right types are ");
              printTypeChain (LTYPE (tree), stderr);
              fprintf (stderr, ",");
              printTypeChain (RTYPE (tree), stderr);
@@ -2250,7 +2279,7 @@ decorateType (ast * tree)
       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
        {
          werror (E_BITWISE_OP);
-         werror (E_CONTINUE, "left & right types are ");
+         werror (W_CONTINUE, "left & right types are ");
          printTypeChain (LTYPE (tree), stderr);
          fprintf (stderr, ",");
          printTypeChain (RTYPE (tree), stderr);
@@ -2312,7 +2341,7 @@ decorateType (ast * tree)
       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
        {
          werror (E_BITWISE_OP);
-         werror (E_CONTINUE, "left & right types are ");
+         werror (W_CONTINUE, "left & right types are ");
          printTypeChain (LTYPE (tree), stderr);
          fprintf (stderr, ",");
          printTypeChain (RTYPE (tree), stderr);
@@ -2671,7 +2700,7 @@ decorateType (ast * tree)
       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
        {
          werror (E_SHIFT_OP_INVALID);
-         werror (E_CONTINUE, "left & right types are ");
+         werror (W_CONTINUE, "left & right types are ");
          printTypeChain (LTYPE (tree), stderr);
          fprintf (stderr, ",");
          printTypeChain (RTYPE (tree), stderr);
@@ -2717,10 +2746,10 @@ decorateType (ast * tree)
        }
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*         casting            */
-/*----------------------------*/
+      /*----------------------------*/
     case CAST:                 /* change the type   */
       /* cannot cast to an aggregate type */
       if (IS_AGGREGATE (LTYPE (tree)))
@@ -2732,23 +2761,51 @@ decorateType (ast * tree)
       /* make sure the type is complete and sane */
       checkTypeSanity(LETYPE(tree), "(cast)");
 
+#if 1
       /* if the right is a literal replace the tree */
-      if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
-       {
-         tree->type = EX_VALUE;
-         tree->opval.val =
-           valCastLiteral (LTYPE (tree),
-                           floatFromVal (valFromType (RETYPE (tree))));
-         tree->left = NULL;
-         tree->right = NULL;
-         TTYPE (tree) = tree->opval.val->type;
-         tree->values.literalFromCast = 1;
-       }
-      else
-       {
-         TTYPE (tree) = LTYPE (tree);
-         LRVAL (tree) = 1;
-       }
+      if (IS_LITERAL (RETYPE (tree))) {
+             if (!IS_PTR (LTYPE (tree))) {
+                     tree->type = EX_VALUE;
+                     tree->opval.val =
+                             valCastLiteral (LTYPE (tree),
+                                             floatFromVal (valFromType (RETYPE (tree))));
+                     tree->left = NULL;
+                     tree->right = NULL;
+                     TTYPE (tree) = tree->opval.val->type;
+                     tree->values.literalFromCast = 1;
+             } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && 
+                        ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
+                     sym_link *rest = LTYPE(tree)->next;
+                     werror(W_LITERAL_GENERIC);                      
+                     TTYPE(tree) = newLink();
+                     DCL_TYPE(TTYPE(tree)) = FPOINTER;
+                     TTYPE(tree)->next = rest;
+                     tree->left->opval.lnk = TTYPE(tree);
+                     LRVAL (tree) = 1;
+             } else {
+                     TTYPE (tree) = LTYPE (tree);
+                     LRVAL (tree) = 1;
+             }
+      } else {
+             TTYPE (tree) = LTYPE (tree);
+             LRVAL (tree) = 1;
+      }
+#else
+      /* if the right is a literal replace the tree */
+      if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
+       tree->type = EX_VALUE;
+       tree->opval.val =
+         valCastLiteral (LTYPE (tree),
+                         floatFromVal (valFromType (RETYPE (tree))));
+       tree->left = NULL;
+       tree->right = NULL;
+       TTYPE (tree) = tree->opval.val->type;
+       tree->values.literalFromCast = 1;
+      } else {
+       TTYPE (tree) = LTYPE (tree);
+       LRVAL (tree) = 1;
+      }
+#endif
 
       TETYPE (tree) = getSpec (TTYPE (tree));
 
@@ -3145,7 +3202,7 @@ decorateType (ast * tree)
 
       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
        {
-         werror (E_RETURN_MISMATCH);
+         werror (W_RETURN_MISMATCH);
          goto errorTreeReturn;
        }