Applied patch #2762516
[fw/sdcc] / src / SDCCast.c
index 4901b9a75c5323e0509646edb40d1aea2129bccc..391408318222ae2d9a396d048770554239edceaf 100644 (file)
@@ -852,7 +852,7 @@ processParms (ast *func,
 
       /* don't perform integer promotion of explicitly typecasted variable arguments
        * if sdcc extensions are enabled */
-      if (options.std_sdcc && 
+      if (options.std_sdcc &&
         (IS_CAST_OP (*actParm) ||
         (IS_AST_SYM_VALUE (*actParm) && AST_VALUES (*actParm, removedCast)) ||
         (IS_AST_LIT_VALUE (*actParm) && AST_VALUES (*actParm, literalFromCast))))
@@ -925,7 +925,7 @@ processParms (ast *func,
       (*actParm)->left = newAst_LINK (defParm->type);
       (*actParm)->right = pTree;
       (*actParm)->decorated = 0; /* force typechecking */
-      decorateType (*actParm, resultType);
+      decorateType (*actParm, IS_GENPTR (defParm->type) ? RESULT_TYPE_GPTR : resultType);
     }
 
   /* make a copy and change the regparm type to the defined parm */
@@ -971,7 +971,7 @@ createIvalType (ast * sym, sym_link * type, initList * ilist)
 /* createIvalStruct - generates initial value for structures       */
 /*-----------------------------------------------------------------*/
 static ast *
-createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
+createIvalStruct (ast *sym, sym_link *type, initList *ilist, ast *rootValue)
 {
   ast *rast = NULL;
   ast *lAst;
@@ -979,7 +979,6 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
   initList *iloop;
   sym_link * etype = getSpec (type);
 
-  sflds = SPEC_STRUCT (type)->fields;
   if (ilist && ilist->type != INIT_DEEP)
     {
       werror (E_INIT_STRUCT, "");
@@ -988,20 +987,20 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
 
   iloop = ilist ? ilist->init.deep : NULL;
 
-  for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
+  for (sflds = SPEC_STRUCT (type)->fields; sflds; sflds = sflds->next)
     {
       /* if we have come to end */
       if (!iloop && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype)))
+        break;
+
+      if (!IS_BITFIELD (sflds->type) || !SPEC_BUNNAMED (sflds->etype))
         {
-          break;
+          sflds->implicit = 1;
+          lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
+          lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
+          rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast, rootValue)), RESULT_TYPE_NONE);
+          iloop = iloop ? iloop->next : NULL;
         }
-
-      sflds->implicit = 1;
-      lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
-      lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
-      rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
-                                                       iloop, rast, rootValue)),
-                           RESULT_TYPE_NONE);
     }
 
   if (iloop)
@@ -1012,7 +1011,7 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
                   sym->opval.val->sym->name);
       else
         werrorfl (sym->filename, sym->lineno, E_INIT_COUNT);
-  }
+    }
 
   return rast;
 }
@@ -1151,7 +1150,7 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
       if (!AST_SYMBOL (rootVal)->islocal || SPEC_STAT (getSpec (type)))
         return NULL;
 
-      for (i=0; i<symsize; i++)
+      for (i = 0; i < symsize; ++i)
         {
           rast = newNode (NULLOP,
                           rast,
@@ -1175,9 +1174,9 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
       unsigned int symsize = getSize (type);
 
       size = getSize (iexpr->ftype);
-      if (symsize && size>symsize)
+      if (symsize && size > symsize)
         {
-          if (size>(symsize+1))
+          if (size > symsize)
             {
               char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
 
@@ -1187,15 +1186,14 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
           size = symsize;
         }
 
-      for (i=0;i<size;i++)
+      for (i = 0; i < size; i++)
         {
           rast = newNode (NULLOP,
                           rast,
                           newNode ('=',
                                    newNode ('[', sym,
                                    newAst_VALUE (valueFromLit ((float) i))),
-                                   newAst_VALUE (valueFromLit (*s))));
-          s++;
+                                   newAst_VALUE (valueFromLit (*s++))));
         }
 
       // now WE don't need iexpr's symbol anymore
@@ -3253,7 +3251,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
               werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
               goto errorTreeReturn;
             }
-          if (IS_ADDRESS_OF_OP(tree->left))
+          if (IS_ADDRESS_OF_OP (tree->left))
             {
               /* replace *&obj with obj */
               return tree->left->left;
@@ -3875,7 +3873,6 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       changePointer(LTYPE(tree));
       checkTypeSanity(LETYPE(tree), "(cast)");
 
-
       /* if 'from' and 'to' are the same remove the superfluous cast,
        * this helps other optimizations */
       if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
@@ -3905,33 +3902,41 @@ decorateType (ast * tree, RESULT_TYPE resultType)
 
 #if 0
       /* if the right is a literal replace the tree */
-      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) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
-                      sym_link *rest = LTYPE(tree)->next;
-                      werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
-                      TTYPE(tree) = newLink(DECLARATOR);
-                      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 {
+      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) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */
+            {
+              sym_link *rest = LTYPE(tree)->next;
+              werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
+              TTYPE(tree) = newLink(DECLARATOR);
+              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 0 // this is already checked, now this could be explicit
       /* if pointer to struct then check names */
@@ -3945,49 +3950,47 @@ decorateType (ast * tree, RESULT_TYPE resultType)
 #endif
       if (IS_ADDRESS_OF_OP(tree->right)
           && IS_AST_SYM_VALUE (tree->right->left)
-          && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
-
-        symbol * sym = AST_SYMBOL (tree->right->left);
-        unsigned int gptype = 0;
-        unsigned int addr = SPEC_ADDR (sym->etype);
+          && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype))
+        {
+          symbol * sym = AST_SYMBOL (tree->right->left);
+          unsigned int gptype = 0;
+          unsigned int addr = SPEC_ADDR (sym->etype);
 
-        if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
-                                        || TARGET_IS_PIC16) )
-          {
-            switch (SPEC_SCLS (sym->etype))
-              {
-              case S_CODE:
-                gptype = GPTYPE_CODE;
-                break;
-              case S_XDATA:
-                gptype = GPTYPE_FAR;
-                break;
-              case S_DATA:
-              case S_IDATA:
-                gptype = GPTYPE_NEAR;
-                break;
-              case S_PDATA:
-                gptype = GPTYPE_XSTACK;
-                break;
-              default:
-                gptype = 0;
+          if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE) || TARGET_IS_PIC16) )
+            {
+              switch (SPEC_SCLS (sym->etype))
+                {
+                case S_CODE:
+                  gptype = GPTYPE_CODE;
+                  break;
+                case S_XDATA:
+                  gptype = GPTYPE_FAR;
+                  break;
+                case S_DATA:
+                case S_IDATA:
+                  gptype = GPTYPE_NEAR;
+                  break;
+                case S_PDATA:
+                  gptype = GPTYPE_XSTACK;
+                  break;
+                default:
+                  gptype = 0;
 
-                if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
-                    gptype = GPTYPE_NEAR;
-              }
-            addr |= gptype << (8*(GPTRSIZE - 1));
-          }
+                  if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
+                      gptype = GPTYPE_NEAR;
+                }
+              addr |= gptype << (8*(GPTRSIZE - 1));
+            }
 
-        tree->type = EX_VALUE;
-        tree->opval.val =
-          valCastLiteral (LTYPE (tree), addr);
-        TTYPE (tree) = tree->opval.val->type;
-        TETYPE (tree) = getSpec (TTYPE (tree));
-        tree->left = NULL;
-        tree->right = NULL;
-        tree->values.literalFromCast = 1;
-        return tree;
-      }
+          tree->type = EX_VALUE;
+          tree->opval.val = valCastLiteral (LTYPE (tree), addr);
+          TTYPE (tree) = tree->opval.val->type;
+          TETYPE (tree) = getSpec (TTYPE (tree));
+          tree->left = NULL;
+          tree->right = NULL;
+          tree->values.literalFromCast = 1;
+          return tree;
+        }
 
       /* handle offsetof macro:            */
       /* #define offsetof(TYPE, MEMBER) \  */
@@ -3997,84 +4000,91 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           && tree->right->left->opval.op == PTR_OP
           && IS_AST_OP (tree->right->left->left)
           && tree->right->left->left->opval.op == CAST
-          && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
-
-        symbol *element = getStructElement (
-          SPEC_STRUCT (LETYPE(tree->right->left)),
-          AST_SYMBOL(tree->right->left->right)
-        );
-
-        if (element) {
-          tree->type = EX_VALUE;
-          tree->opval.val = valCastLiteral (
-            LTYPE (tree),
-            element->offset
-            + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
+          && IS_AST_LIT_VALUE(tree->right->left->left->right))
+        {
+          symbol *element = getStructElement (
+            SPEC_STRUCT (LETYPE(tree->right->left)),
+            AST_SYMBOL(tree->right->left->right)
           );
 
-          TTYPE (tree) = tree->opval.val->type;
-          TETYPE (tree) = getSpec (TTYPE (tree));
-          tree->left = NULL;
-          tree->right = NULL;
-          return tree;
-        }
+          if (element)
+            {
+              tree->type = EX_VALUE;
+              tree->opval.val = valCastLiteral (
+                LTYPE (tree),
+                element->offset
+                + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
+              );
+
+            TTYPE (tree) = tree->opval.val->type;
+            TETYPE (tree) = getSpec (TTYPE (tree));
+            tree->left = NULL;
+            tree->right = NULL;
+            return tree;
+          }
       }
 
       /* if the right is a literal replace the tree */
-      if (IS_LITERAL (RETYPE (tree))) {
-        #if 0
-        if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
-          /* rewrite      (type *)litaddr
-             as           &temp
-             and define   type at litaddr temp
-             (but only if type's storage class is not generic)
-          */
-          ast *newTree = newNode ('&', NULL, NULL);
-          symbol *sym;
-
-          TTYPE (newTree) = LTYPE (tree);
-          TETYPE (newTree) = getSpec(LTYPE (tree));
-
-          /* define a global symbol at the casted address*/
-          sym = newSymbol(genSymName (0), 0);
-          sym->type = LTYPE (tree)->next;
-          if (!sym->type)
-            sym->type = newLink (V_VOID);
-          sym->etype = getSpec(sym->type);
-          SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
-          sym->lineDef = tree->lineno;
-          sym->cdef = 1;
-          sym->isref = 1;
-          SPEC_STAT (sym->etype) = 1;
-          SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
-          SPEC_ABSA(sym->etype) = 1;
-          addSym (SymbolTab, sym, sym->name, 0, 0, 0);
-          allocGlobal (sym);
-
-          newTree->left = newAst_VALUE(symbolVal(sym));
-          newTree->left->filename = tree->filename;
-          newTree->left->lineno = tree->lineno;
-          LTYPE (newTree) = sym->type;
-          LETYPE (newTree) = sym->etype;
-          LLVAL (newTree) = 1;
-          LRVAL (newTree) = 0;
-          TLVAL (newTree) = 1;
-          return newTree;
-        }
-        #endif
-        if (!IS_PTR (LTYPE (tree))) {
-          tree->type = EX_VALUE;
-          tree->opval.val =
-          valCastLiteral (LTYPE (tree),
-                          floatFromVal (valFromType (RTYPE (tree))));
-          TTYPE (tree) = tree->opval.val->type;
-          tree->left = NULL;
-          tree->right = NULL;
-          tree->values.literalFromCast = 1;
-          TETYPE (tree) = getSpec (TTYPE (tree));
-          return tree;
+      if (IS_LITERAL (RETYPE (tree)))
+        {
+          #if 0
+          if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) )
+            {
+              /* rewrite      (type *)litaddr
+                 as           &temp
+                 and define   type at litaddr temp
+                 (but only if type's storage class is not generic)
+              */
+              ast *newTree = newNode ('&', NULL, NULL);
+              symbol *sym;
+
+              TTYPE (newTree) = LTYPE (tree);
+              TETYPE (newTree) = getSpec(LTYPE (tree));
+
+              /* define a global symbol at the casted address*/
+              sym = newSymbol(genSymName (0), 0);
+              sym->type = LTYPE (tree)->next;
+              if (!sym->type)
+                sym->type = newLink (V_VOID);
+              sym->etype = getSpec(sym->type);
+              SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
+              sym->lineDef = tree->lineno;
+              sym->cdef = 1;
+              sym->isref = 1;
+              SPEC_STAT (sym->etype) = 1;
+              SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
+              SPEC_ABSA(sym->etype) = 1;
+              addSym (SymbolTab, sym, sym->name, 0, 0, 0);
+              allocGlobal (sym);
+
+              newTree->left = newAst_VALUE(symbolVal(sym));
+              newTree->left->filename = tree->filename;
+              newTree->left->lineno = tree->lineno;
+              LTYPE (newTree) = sym->type;
+              LETYPE (newTree) = sym->etype;
+              LLVAL (newTree) = 1;
+              LRVAL (newTree) = 0;
+              TLVAL (newTree) = 1;
+              return newTree;
+            }
+          #endif
+          if (!IS_PTR (LTYPE (tree)))
+            {
+              tree->type = EX_VALUE;
+              tree->opval.val =
+                valCastLiteral (LTYPE (tree), floatFromVal (valFromType (RTYPE (tree))));
+              TTYPE (tree) = tree->opval.val->type;
+              tree->left = NULL;
+              tree->right = NULL;
+              tree->values.literalFromCast = 1;
+              TETYPE (tree) = getSpec (TTYPE (tree));
+              return tree;
+            }
+        }
+      if (IS_GENPTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) && !IS_GENPTR (RTYPE (tree)) && (resultType != RESULT_TYPE_GPTR))
+        {
+          DCL_TYPE (LTYPE (tree)) = DCL_TYPE (RTYPE (tree));
         }
-      }
       TTYPE (tree) = LTYPE (tree);
       LRVAL (tree) = 1;
 
@@ -4677,8 +4687,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           printFromToType(RTYPE(tree), LTYPE(tree));
         }
 
-      TETYPE (tree) = getSpec (TTYPE (tree) =
-                               LTYPE (tree));
+      TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
       RRVAL (tree) = 1;
       LLVAL (tree) = 1;
       if (!tree->initMode ) {
@@ -4784,7 +4793,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
             decorateType (newNode (CAST,
                           newAst_LINK (copyLinkChain (currFunc->type->next)),
                                         tree->right),
-                          RESULT_TYPE_NONE);
+                          IS_GENPTR (currFunc->type->next) ? RESULT_TYPE_GPTR : RESULT_TYPE_NONE);
         }
 
       RRVAL (tree) = 1;