fixed bug #456966
[fw/sdcc] / src / SDCCast.c
index 7421c30e0fa34bebcfbd96f6a04fda5b004fdf04..0a429066c6c0114f565ce4224a0d5a1aeac55ca7 100644 (file)
@@ -629,7 +629,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 +743,17 @@ 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");
-    }
+  if (compareType (defParm->type, actParm->ftype) == 0) {
+    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)
@@ -892,7 +892,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
            ast *aSym;
            
            aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
-           //aSym = decorateType (resolveSymbols (aSym));
+           aSym = decorateType (resolveSymbols (aSym));
            rast = createIval (aSym, type->next, iloop, rast);
            iloop = (iloop ? iloop->next : NULL);
            if (!iloop)
@@ -1036,67 +1036,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));
     }
   }
   
@@ -1139,7 +1107,7 @@ gatherAutoInit (symbol * autoChain)
          /* insert the symbol into the symbol table */
          /* with level = 0 & name = rname       */
          newSym = copySymbol (sym);
-         addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
+         addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
 
          /* now lift the code to main */
          if (IS_AGGREGATE (sym->type))
@@ -1235,8 +1203,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)
@@ -1253,6 +1221,7 @@ processBlockVars (ast * tree, int *stack, int action)
 
 /*-----------------------------------------------------------------*/
 /* constExprValue - returns the value of a constant expression     */
+/*                  or NULL if it is not a constant expression     */
 /*-----------------------------------------------------------------*/
 value *
 constExprValue (ast * cexpr, int check)
@@ -2022,10 +1991,10 @@ decorateType (ast * tree)
 
   switch (tree->opval.op)
     {
-/*------------------------------------------------------------------*/
-/*----------------------------*/
-      /*        array node          */
-/*----------------------------*/
+           /*------------------------------------------------------------------*/
+           /*----------------------------*/
+           /*        array node          */
+           /*----------------------------*/
     case '[':
 
       /* determine which is the array & which the index */
@@ -2064,10 +2033,10 @@ decorateType (ast * tree)
       }
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      struct/union          */
-/*----------------------------*/
+      /*----------------------------*/
     case '.':
       /* if this is not a structure */
       if (!IS_STRUCT (LTYPE (tree)))
@@ -2081,10 +2050,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 +2105,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 +2251,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 +2313,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 +2672,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 +2718,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 +2733,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 +3174,7 @@ decorateType (ast * tree)
 
       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
        {
-         werror (E_RETURN_MISMATCH);
+         werror (W_RETURN_MISMATCH);
          goto errorTreeReturn;
        }