1) SDCCast.c - allow cast of ZERO to generic pointer (Special case for NULL)
[fw/sdcc] / src / SDCCast.c
index 6b95246f14fd4644807eef077972e5e95c2edd71..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,18 +744,46 @@ 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)
     {
@@ -1036,67 +1065,35 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
 
 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
+  ast *ast;
+  symbol *newSym;
 
   if (getenv("TRY_THE_NEW_INITIALIZER")) {
 
     if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
       fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
-              "with -mmcs51 and --model-large\n");
+              "with -mmcs51 and --model-large");
       exit(404);
     }
 
-    if (SPEC_OCLS(sym->type->next)!=xdata) {
-      fprintf (stderr, "Can't \"TRY_THE_NEW_INITALIZER\" unless in xdata\n");
-      exit (405);
-    }
-    
-    if (getSize(sym->type) > 64) { // else it is'n worth it: do it the old way
-      // emit the inital values in cseg, then copy it to where it belongs
-      initList *iLoop;
-      int count, size=getSize(sym->type->next);
-      
-      if (ival->type != INIT_DEEP) {
-       werror (E_INIT_STRUCT, sym->name);
-       return NULL;
-      }
-      
-      tfprintf (code->oFile, "; initial data for %s\n", sym->name);
-      // TODO: this has to be a unique name
-      tfprintf (code->oFile, "_init_%s:", sym->name);
-      
-      for (count=0, iLoop=ival->init.deep; iLoop; iLoop=iLoop->next) {
-       count += size;
-       printIval (sym, sym->type->next, iLoop, code->oFile);
-      }
-      
-      // Now we only have to copy <count> bytes from cseg.
-      // This is VERY -mmcs51 --model-large specific for now, 
-      // in fact we should generate
-      // some icodes here that does the trick. But ok: experimental
-      // Trick: memcpy (sym->name, _init_(sym->name), count)
-      fprintf (statsg->oFile, ";       %s      %d\n", filename, sym->lineDef);
-      fprintf (statsg->oFile, ";       copy initial data from cseg _init_%s to %s\n", 
-              sym->name, sym->name);
-      fprintf (statsg->oFile, "        mov dptr,#_memcpy_PARM_2\n");
-      fprintf (statsg->oFile, "        mov a,#_%s\n", sym->name);
-      fprintf (statsg->oFile, "        movx @dptr,a\n");
-      fprintf (statsg->oFile, "        inc dptr\n");
-      fprintf (statsg->oFile, "        mov a,#(_%s>>8)\n", sym->name);
-      fprintf (statsg->oFile, "        movx @dptr,a\n");
-      fprintf (statsg->oFile, "        inc dptr\n");
-      fprintf (statsg->oFile, "        mov a,#%02x;    from cseg\n", 1);
-      fprintf (statsg->oFile, "        movx @dptr,a\n");
-      fprintf (statsg->oFile, "        mov dptr,#_memcpy_PARM_3\n");
-      fprintf (statsg->oFile, "        mov a,#(%d>>0); number of bytes\n", count);
-      fprintf (statsg->oFile, "        movx @dptr,a\n");
-      fprintf (statsg->oFile, "        inc dptr\n");
-      fprintf (statsg->oFile, "        mov a,#(%d>>8)\n", count);
-      fprintf (statsg->oFile, "        movx @dptr,a\n");
-      fprintf (statsg->oFile, "        mov dptr,#_init_%s\n", sym->name);
-      fprintf (statsg->oFile, "        mov b,#%02x;    only to xseg for now\n", 2);
-      fprintf (statsg->oFile, "        lcall _memcpy\n");
-      
-      return NULL;
+    if (SPEC_OCLS(sym->etype)==xdata &&
+       getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
+
+      // copy this symbol
+      newSym=copySymbol (sym);
+      SPEC_OCLS(newSym->etype)=code;
+      sprintf (newSym->name, "%s_init__", sym->name);
+      sprintf (newSym->rname,"%s_init__", sym->rname);
+      addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
+
+      // emit it in the static segment
+      addSet(&statsg->syms, newSym);
+
+      // now memcpy() the entire array from cseg
+      ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
+                  newAst_VALUE (symbolVal (sym)), 
+                  newAst_VALUE (symbolVal (newSym)));
+      return decorateType(resolveSymbols(ast));
     }
   }
   
@@ -1235,8 +1232,8 @@ processBlockVars (ast * tree, int *stack, int action)
 
       if (action == ALLOCATE)
        {
-         autoInit = gatherAutoInit (tree->values.sym);
          *stack += allocVariables (tree->values.sym);
+         autoInit = gatherAutoInit (tree->values.sym);
 
          /* if there are auto inits then do them */
          if (autoInit)
@@ -2022,10 +2019,10 @@ decorateType (ast * tree)
 
   switch (tree->opval.op)
     {
-/*------------------------------------------------------------------*/
-/*----------------------------*/
-      /*        array node          */
-/*----------------------------*/
+           /*------------------------------------------------------------------*/
+           /*----------------------------*/
+           /*        array node          */
+           /*----------------------------*/
     case '[':
 
       /* determine which is the array & which the index */
@@ -2064,10 +2061,10 @@ decorateType (ast * tree)
       }
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      struct/union          */
-/*----------------------------*/
+      /*----------------------------*/
     case '.':
       /* if this is not a structure */
       if (!IS_STRUCT (LTYPE (tree)))
@@ -2081,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)))
@@ -2136,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);
@@ -2282,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);
@@ -2344,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);
@@ -2703,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);
@@ -2749,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)))
@@ -2764,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));
 
@@ -3177,7 +3202,7 @@ decorateType (ast * tree)
 
       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
        {
-         werror (E_RETURN_MISMATCH);
+         werror (W_RETURN_MISMATCH);
          goto errorTreeReturn;
        }