* src/SDCCglue.c: fixed bug #1864582: multiple definition of char
[fw/sdcc] / src / SDCCast.c
index 97581fee14dd9027cef9b8f717dc3f4eef0d7aae..94a1c5a24e80b7a06776e58d3b7fa8a5bf978e0c 100644 (file)
@@ -84,12 +84,11 @@ static ast *
 newAst_ (unsigned type)
 {
   ast *ex;
-  static int oldLineno = 0;
 
   ex = Safe_alloc ( sizeof (ast));
 
   ex->type = type;
-  ex->lineno = (noLineno ? oldLineno : lexLineno);
+  ex->lineno = (noLineno ? 0 : lexLineno);
   ex->filename = lexFilename;
   ex->level = NestLevel;
   ex->block = currBlockno;
@@ -223,6 +222,7 @@ copyAst (ast * src)
   dest = Safe_alloc ( sizeof (ast));
 
   dest->type = src->type;
+  dest->filename = src->filename;
   dest->lineno = src->lineno;
   dest->level = src->level;
   dest->funcName = src->funcName;
@@ -616,17 +616,18 @@ resolveChildren:
   return tree;
 }
 
-/*-----------------------------------------------------------------*/
-/* setAstLineno - walks a ast tree & sets the line number          */
-/*-----------------------------------------------------------------*/
-int setAstLineno (ast * tree, int lineno)
+/*------------------------------------------------------------------------*/
+/* setAstFileLine - walks a ast tree & sets the file name and line number */
+/*------------------------------------------------------------------------*/
+int setAstFileLine (ast * tree, char *filename, int lineno)
 {
   if (!tree)
     return 0;
 
+  tree->filename = filename;
   tree->lineno = lineno;
-  setAstLineno (tree->left, lineno);
-  setAstLineno (tree->right, lineno);
+  setAstFileLine (tree->left, filename, lineno);
+  setAstFileLine (tree->right, filename, lineno);
   return 0;
 }
 
@@ -853,8 +854,12 @@ processParms (ast *func,
       ast *newType = NULL;
       sym_link *ftype;
 
-      if (IS_CAST_OP (*actParm)
-          || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
+      /* don't perform integer promotion of explicitly typecasted variable arguments
+       * if sdcc extensions are enabled */
+      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))))
         {
           /* Parameter was explicitly typecast; don't touch it. */
           return 0;
@@ -886,6 +891,7 @@ processParms (ast *func,
           /* cast required; change this op to a cast. */
           (*actParm)->decorated = 0;
            *actParm = newNode (CAST, newType, *actParm);
+          (*actParm)->filename = (*actParm)->right->filename;
           (*actParm)->lineno = (*actParm)->right->lineno;
 
           decorateType (*actParm, RESULT_TYPE_NONE);
@@ -996,10 +1002,14 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
 
     }
 
-  if (iloop) {
-    werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
-              W_EXCESS_INITIALIZERS, "struct",
-              sym->opval.val->sym->name);
+  if (iloop)
+    {
+      if (IS_AST_VALUE (sym))
+        werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
+                  W_EXCESS_INITIALIZERS, "struct",
+                  sym->opval.val->sym->name);
+      else
+        werrorfl (sym->filename, sym->lineno, E_INIT_COUNT);
   }
 
   return rast;
@@ -1298,7 +1308,7 @@ gatherAutoInit (symbol * autoChain)
                             list2expr (sym->ival));
           }
 
-          setAstLineno (work, sym->lineDef);
+          setAstFileLine (work, sym->fileDef, sym->lineDef);
 
           sym->ival = NULL;
           if (staticAutos)
@@ -1319,8 +1329,9 @@ gatherAutoInit (symbol * autoChain)
           }
 
           /* update lineno for error msg */
+          filename = sym->fileDef;
           lineno = sym->lineDef;
-          setAstLineno (ilist->init.node, sym->lineDef);
+          setAstFileLine (ilist->init.node, sym->fileDef, sym->lineDef);
 
           if (IS_AGGREGATE (sym->type)) {
             work = initAggregates (sym, sym->ival, NULL);
@@ -1335,7 +1346,7 @@ gatherAutoInit (symbol * autoChain)
           }
 
           // just to be sure
-          setAstLineno (work, sym->lineDef);
+          setAstFileLine (work, sym->fileDef, sym->lineDef);
 
           sym->ival = NULL;
           if (init)
@@ -1375,16 +1386,18 @@ stringToSymbol (value * val)
   unsigned int size;
 
   // have we heard this before?
-  for (sp=statsg->syms; sp; sp=sp->next) {
-    sym=sp->item;
-    size = getSize (sym->type);
-    if (sym->isstrlit && size == getSize (val->type) &&
-        !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
-      // yes, this is old news. Don't publish it again.
-      sym->isstrlit++; // but raise the usage count
-      return symbolVal(sym);
+  for (sp = statsg->syms; sp; sp = sp->next)
+    {
+      sym = sp->item;
+      size = getSize (sym->type);
+      if (sym->isstrlit && size == getSize (val->type) &&
+          !memcmp (SPEC_CVAL (sym->etype).v_char, SPEC_CVAL (val->etype).v_char, size))
+        {
+          // yes, this is old news. Don't publish it again.
+          sym->isstrlit++; // but raise the usage count
+          return symbolVal (sym);
+        }
     }
-  }
 
   SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
   sym = newSymbol (name, 0);    /* make it @ level 0 */
@@ -1651,7 +1664,7 @@ isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
             {
 
               *end = newNode ('+', condExpr->left->right,
-                              newAst_VALUE (constVal ("1")));
+                              newAst_VALUE (constCharVal (1)));
               break;
             }
           return FALSE;
@@ -2072,7 +2085,7 @@ replLoopSym (ast * body, symbol * sym)
           body->type = EX_OP;
           body->opval.op = '-';
           body->left = newAst_VALUE (symbolVal (sym));
-          body->right = newAst_VALUE (constVal ("1"));
+          body->right = newAst_VALUE (constCharVal (1));
 
         }
 
@@ -2112,7 +2125,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
                             end));
 
   replLoopSym (loop->left, sym);
-  setAstLineno (rloop, init->lineno);
+  setAstFileLine (rloop, init->filename, init->lineno);
 
   rloop = newNode (NULLOP,
                    newNode ('=',
@@ -2124,7 +2137,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
                                          newNode (NULLOP,
                                                   newNode (SUB_ASSIGN,
                                                            newAst_VALUE (symbolVal (sym)),
-                                                           newAst_VALUE (constVal ("1"))),
+                                                           newAst_VALUE (constCharVal (1))),
                                                   rloop))));
 
   rloop->lineno=init->lineno;
@@ -2275,6 +2288,7 @@ addCast (ast *tree, RESULT_TYPE resultType, bool promote)
     }
   tree->decorated = 0;
   tree = newNode (CAST, newAst_LINK (newLink), tree);
+  tree->filename = tree->right->filename;
   tree->lineno = tree->right->lineno;
   /* keep unsigned type during cast to smaller type,
      but not when promoting from char to int */
@@ -2466,6 +2480,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
 /*----------------------------*/
 /*   leaf has been reached    */
 /*----------------------------*/
+  filename = tree->filename;
   lineno = tree->lineno;
   /* if this is of type value */
   /* just get the type        */
@@ -3129,9 +3144,10 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                   litTree->right = newNode ('*',
                                             litTree->right,
                                             copyAst (tree->right));
+                  litTree->right->filename = tree->filename;
                   litTree->right->lineno = tree->lineno;
 
-                  tree->right->opval.val = constVal ("1");
+                  tree->right->opval.val = constCharVal (1);
                   decorateType (parent, resultType);
                 }
               else
@@ -3525,7 +3541,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         {
           tree->type = EX_VALUE;
           tree->left = tree->right = NULL;
-          tree->opval.val = constVal ("0");
+          tree->opval.val = constCharVal (0);
           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
           return tree;
         }
@@ -3640,7 +3656,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
 
           /* optimize bit-result, even if we optimize a buggy source */
           tree->type = EX_VALUE;
-          tree->opval.val = constVal ("1");
+          tree->opval.val = constCharVal (1);
         }
       else
         tree->left = addCast (tree->left, resultTypeProp, TRUE);
@@ -3674,8 +3690,9 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           tree->opval.op = '?';
           tree->left  = tree->left->left;
           tree->right = newNode (':',
-                                  newAst_VALUE (constVal ("1")),
-                                  newAst_VALUE (constVal ("0")));
+                                  newAst_VALUE (constCharVal (1)),
+                                  newAst_VALUE (constCharVal (0)));
+          tree->right->filename = tree->filename;
           tree->right->lineno = tree->lineno;
           tree->decorated = 0;
           return decorateType (tree, resultType);
@@ -3797,7 +3814,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                       (tree->opval.op == LEFT_OP ? "left" : "right"));
               tree->type = EX_VALUE;
               tree->left = tree->right = NULL;
-              tree->opval.val = constVal ("0");
+              tree->opval.val = constCharVal (0);
               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
               return tree;
             }
@@ -3821,10 +3838,14 @@ 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 'from' and 'to' are the same remove the superfluous cast,
+       * this helps other optimizations */
       if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
         {
+          /* mark that the explicit cast has been removed,
+           * for proper processing (no integer promotion) of explicitly typecasted variable arguments */
+          tree->right->values.removedCast = 1;
           return tree->right;
         }
 
@@ -3994,6 +4015,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           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;
@@ -4139,9 +4161,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                 if (!options.lessPedantic)
                   werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
                           ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
-                return decorateType (newAst_VALUE (constVal (
-                                   ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
-                                                   resultType);
+                return decorateType (newAst_VALUE (constCharVal ((unsigned char)(ccr_result == CCR_ALWAYS_TRUE))), resultType);
               case CCR_OK:
               default:
                 break;
@@ -4164,9 +4184,11 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           /* (unsigned value) ? 1 : 0 */
           tree->opval.op = '?';
           tree->right = newNode (':',
-                                  newAst_VALUE (constVal ("1")),
+                                  newAst_VALUE (constCharVal (1)),
                                   tree->right); /* val 0 */
+          tree->right->filename = tree->filename;
           tree->right->lineno = tree->lineno;
+          tree->right->left->filename = tree->filename;
           tree->right->left->lineno = tree->lineno;
           tree->decorated = 0;
           return decorateType (tree, resultType);
@@ -4271,6 +4293,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
             tree->opval.op = transformedOp;
             tree->decorated = 0;
             tree = newNode ('!', tree, NULL);
+            tree->filename = tree->left->filename;
             tree->lineno = tree->left->lineno;
             return decorateType (tree, resultType);
           }
@@ -4965,6 +4988,7 @@ createBlock (symbol * decl, ast * body)
   ex->values.sym = decl;
 
   ex->level++;
+  ex->filename = NULL;
   ex->lineno = 0;
   return ex;
 }
@@ -5001,6 +5025,7 @@ createLabel (symbol * label, ast * stmnt)
   label->islbl = 1;
   label->key = labelKey++;
   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
+  rValue->filename = NULL;
   rValue->lineno = 0;
 
   return rValue;
@@ -5088,6 +5113,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
            (int) ulFromVal (caseVal->opval.val));
 
   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
+  rexpr->filename = 0;
   rexpr->lineno = 0;
   return rexpr;
 }
@@ -5323,10 +5349,12 @@ createWhile (symbol * trueLabel, symbol * continueLabel,
   /* put the continue label */
   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
   condExpr = createLabel (continueLabel, condExpr);
+  condExpr->filename = NULL;
   condExpr->lineno = 0;
 
   /* put the body label in front of the body */
   whileBody = createLabel (trueLabel, whileBody);
+  whileBody->filename = NULL;
   whileBody->lineno = 0;
   /* put a jump to continue at the end of the body */
   /* and put break label at the end of the body */
@@ -5795,12 +5823,12 @@ optimizeCompare (ast * root)
         case '>':
         case '<':
         case NE_OP:
-          optExpr = newAst_VALUE (constVal ("0"));
+          optExpr = newAst_VALUE (constCharVal (0));
           break;
         case GE_OP:
         case LE_OP:
         case EQ_OP:
-          optExpr = newAst_VALUE (constVal ("1"));
+          optExpr = newAst_VALUE (constCharVal (1));
           break;
         }
 
@@ -5950,7 +5978,7 @@ static void
 fixupInlineLabel (symbol * sym)
 {
   char name[SDCC_NAME_MAX + 1];
-  
+
   SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
   strcpy (sym->name, name);
 }
@@ -5963,12 +5991,12 @@ fixupInlineLabel (symbol * sym)
 static void
 copyAstLoc (ast * dest, ast * src)
 {
-  dest->lineno = src->lineno;
   dest->filename = src->filename;
+  dest->lineno = src->lineno;
   dest->level = src->level;
   dest->block = src->block;
   dest->seqPoint = src->seqPoint;
-  
+
 }
 
 
@@ -6281,14 +6309,19 @@ expandInlineFuncs (ast * tree, ast * block)
           while (args)
             {
               symbol * temparg;
-              ast * passedarg;
               ast * assigntree;
-              symbol * parm = copySymbol (args->sym);
+              symbol * parm;
+              ast * passedarg = inlineFindParm (tree->right, argIndex);
+
+              if (!passedarg)
+                {
+                  werror(E_TOO_FEW_PARMS);
+                  break;
+                }
 
               temparg = inlineTempVar (args->sym->type, tree->level+1);
               inlineAddDecl (temparg, inlinetree, FALSE);
 
-              passedarg = inlineFindParm (tree->right, argIndex);
               assigntree = newNode ('=',
                                     newAst_VALUE (symbolVal (temparg)),
                                     passedarg);
@@ -6296,6 +6329,7 @@ expandInlineFuncs (ast * tree, ast * block)
                                            assigntree,
                                            inlinetree->right);
 
+              parm = copySymbol (args->sym);
               inlineAddDecl (parm, inlinetree2, FALSE);
               parm->_isparm = 0;