* src/hc08/ralloc.c (rematStr): fixed bug #879282
[fw/sdcc] / src / SDCCast.c
index 0a289dbede28214a505a5711773b8c63afc9bbe9..56d377602d3544ac124199651ae5eea03b7aca42 100644 (file)
@@ -84,6 +84,7 @@ newAst_ (unsigned type)
   ex->level = NestLevel;
   ex->block = currBlockno;
   ex->initMode = inInitMode;
+  ex->seqPoint = seqPointNo;
   return ex;
 }
 
@@ -343,7 +344,7 @@ hasSEFcalls (ast * tree)
 /*-----------------------------------------------------------------*/
 /* isAstEqual - compares two asts & returns 1 if they are equal    */
 /*-----------------------------------------------------------------*/
-int 
+static int
 isAstEqual (ast * t1, ast * t2)
 {
   if (!t1 && !t2)
@@ -429,7 +430,8 @@ resolveSymbols (ast * tree)
                               tree->trueLabel->name)))
            tree->trueLabel = csym;
          else
-           werror (E_LABEL_UNDEF, tree->trueLabel->name);
+           werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
+                     tree->trueLabel->name);
        }
 
       if (tree->falseLabel)
@@ -439,7 +441,8 @@ resolveSymbols (ast * tree)
                               tree->falseLabel->name)))
            tree->falseLabel = csym;
          else
-           werror (E_LABEL_UNDEF, tree->falseLabel->name);
+           werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
+                     tree->falseLabel->name);
        }
 
     }
@@ -454,7 +457,8 @@ resolveSymbols (ast * tree)
                              tree->opval.val->sym->name);
 
       if (!csym)
-       werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
+       werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
+                 tree->opval.val->sym->name);
       else
        tree->opval.val->sym = csym;
 
@@ -493,7 +497,9 @@ resolveSymbols (ast * tree)
                tree->opval.val->sym->etype = newIntLink ();
              tree->opval.val->etype = tree->opval.val->etype;
              tree->opval.val->type = tree->opval.val->sym->type;
-             werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
+             werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
+                       tree->opval.val->sym->name);
+             //tree->opval.val->sym->undefined = 1;
              allocVariables (tree->opval.val->sym);
            }
          else
@@ -670,6 +676,8 @@ processParms (ast * func,
   /* exist and this is not defined as a variable arg   */
   if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
     {
+      //if (func->type==EX_VALUE && func->opval.val->sym->undefined)
+      //  return 1; /* Already gave them an undefined function error */
       werror (E_TOO_MANY_PARMS);
       return 1;
     }
@@ -857,8 +865,9 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist)
     }
 
   if (iloop) {
-    werror (W_EXCESS_INITIALIZERS, "struct", 
-           sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
+    werrorfl (filename, sym->opval.val->sym->lineDef,
+             W_EXCESS_INITIALIZERS, "struct", 
+             sym->opval.val->sym->name);
   }
 
   return rast;
@@ -918,7 +927,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
            char *name=sym->opval.val->sym->name;
            int lineno=sym->opval.val->sym->lineDef;
            
-           werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
+           werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
        }
     }
     else
@@ -943,7 +952,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
                // there has to be a better way
                char *name=sym->opval.val->sym->name;
                int lineno=sym->opval.val->sym->lineDef;
-               werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
+               werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
                
                break;
            }
@@ -986,6 +995,15 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
       char *s = SPEC_CVAL (iexpr->etype).v_char;
       int i = 0;
       int size = getSize (iexpr->ftype);
+      int symsize = getSize (type);
+      
+      if (size>symsize)
+        {
+         if (size>(symsize+1))
+           werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
+                     "string", sym->opval.val->sym->name);
+         size = symsize;
+       }
 
       for (i=0;i<size;i++)
        {
@@ -1108,8 +1126,9 @@ gatherAutoInit (symbol * autoChain)
            work = initAggregates (sym, sym->ival, NULL);
          } else {
            if (getNelements(sym->type, sym->ival)>1) {
-             werror (W_EXCESS_INITIALIZERS, "scalar", 
-                     sym->name, sym->lineDef);
+             werrorfl (filename, sym->lineDef,
+                       W_EXCESS_INITIALIZERS, "scalar", 
+                       sym->name);
            }
            work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
                            list2expr (sym->ival));
@@ -1143,8 +1162,9 @@ gatherAutoInit (symbol * autoChain)
            work = initAggregates (sym, sym->ival, NULL);
          } else {
            if (getNelements(sym->type, sym->ival)>1) {
-             werror (W_EXCESS_INITIALIZERS, "scalar", 
-                     sym->name, sym->lineDef);
+             werrorfl (filename, sym->lineDef,
+                       W_EXCESS_INITIALIZERS, "scalar", 
+                       sym->name);
            }
            work = newNode ('=', newAst_VALUE (symbolVal (sym)),
                            list2expr (sym->ival));
@@ -1574,7 +1594,7 @@ astHasSymbol (ast * tree, symbol * sym)
       else
        return FALSE;
     }
-  
+
   return astHasSymbol (tree->left, sym) ||
     astHasSymbol (tree->right, sym);
 }
@@ -1726,7 +1746,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
     case '?':
     case ':':
     case SIZEOF:               /* evaluate wihout code generation */
-      
+
       if (IS_AST_SYM_VALUE (pbody->left) &&
          isSymbolEqual (AST_SYMBOL (pbody->left), sym))
        return FALSE;
@@ -1762,7 +1782,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 
       if (astHasVolatile (pbody->left))
        return FALSE;
-      
+
       if (astHasDeref(pbody->right)) return FALSE;
 
       return isConformingBody (pbody->left, sym, body) &&
@@ -2089,6 +2109,28 @@ decorateType (ast * tree)
   {
     ast *dtl, *dtr;
 
+    #if 0
+    if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
+      {
+        if (tree->left && tree->left->type == EX_OPERAND
+           && (tree->left->opval.op == INC_OP
+               || tree->left->opval.op == DEC_OP)
+           && tree->left->left)
+         {
+           tree->left->right = tree->left->left;
+           tree->left->left = NULL;
+         }
+        if (tree->right && tree->right->type == EX_OPERAND
+           && (tree->right->opval.op == INC_OP
+               || tree->right->opval.op == DEC_OP)
+           && tree->right->left)
+         {
+           tree->right->right = tree->right->left;
+           tree->right->left = NULL;
+         }
+      }
+    #endif
+    
     dtl = decorateType (tree->left);
     /* delay right side for '?' operator since conditional macro expansions might
        rely on this */
@@ -2340,7 +2382,7 @@ decorateType (ast * tree)
          }
 
          TTYPE (tree) =
-           computeType (LTYPE (tree), RTYPE (tree));
+           computeType (LTYPE (tree), RTYPE (tree), FALSE);
          TETYPE (tree) = getSpec (TTYPE (tree));
 
           /* if left is a literal exchange left & right */
@@ -2467,8 +2509,6 @@ decorateType (ast * tree)
        wtree = optimizeSWAP (tree);
        if (wtree != tree)
          return decorateType (wtree);
-        
-       // fall through
       }
 
       /* if left is a literal exchange left & right */
@@ -2495,6 +2535,8 @@ decorateType (ast * tree)
              decorateType (parent);
            }
         }
+      /* fall through */
+
       /*------------------------------------------------------------------*/
       /*----------------------------*/
       /*  bitwise xor               */
@@ -2536,7 +2578,8 @@ decorateType (ast * tree)
       /* if right is a literal and */
       /* we can find a 2nd literal in a xor-tree then */
       /* rearrange the tree */
-      if (IS_LITERAL (RTYPE (tree)))
+      if (IS_LITERAL (RTYPE (tree)) &&
+          tree->opval.op == '^') /* the same source is used by 'bitwise or' */
        {
          ast *parent;
          ast *litTree = searchLitOp (tree, &parent, "^");
@@ -2553,7 +2596,10 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           FALSE));
+
+      return tree;
 
       /*------------------------------------------------------------------*/
       /*----------------------------*/
@@ -2581,7 +2627,8 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           TRUE));
 
       /* if right is a literal and */
       /* left is also a division by a literal then */
@@ -2646,7 +2693,8 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           TRUE));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2758,13 +2806,8 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
-
-      /* promote result to int if left & right are char
-        this will facilitate hardware multiplies 8bit x 8bit = 16bit */
-      if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
-       SPEC_NOUN(TETYPE(tree)) = V_INT;
-      }
+                                           RTYPE (tree),
+                                           TRUE));
 
       return tree;
 
@@ -2895,7 +2938,8 @@ decorateType (ast * tree)
       else
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 computeType (LTYPE (tree),
-                                             RTYPE (tree)));
+                                             RTYPE (tree),
+                                             FALSE));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2994,7 +3038,8 @@ decorateType (ast * tree)
       else
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 computeType (LTYPE (tree),
-                                             RTYPE (tree)));
+                                             RTYPE (tree),
+                                             FALSE));
 
       LRVAL (tree) = RRVAL (tree) = 1;
 
@@ -3134,28 +3179,43 @@ decorateType (ast * tree)
          return tree;
        }
 
+      LRVAL (tree) = RRVAL (tree) = 1;
+      if (tree->opval.op == LEFT_OP)
+       {
+         /* promote char to int */
+         TETYPE (tree) = getSpec (TTYPE (tree) =
+                                  computeType (LTYPE (tree),
+                                               LTYPE (tree), /* no, not RTYPE! */
+                                               TRUE));
+       }
+      else /* RIGHT_OP */
+       {
+         /* no promotion necessary */
+         TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
+         if (IS_LITERAL (TTYPE (tree)))
+           SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
+       }
+
       /* if only the right side is a literal & we are
          shifting more than size of the left operand then zero */
       if (IS_LITERAL (RTYPE (tree)) &&
-         ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
-         (getSize (LTYPE (tree)) * 8))
+         ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
+         (getSize (TETYPE (tree)) * 8))
        {
          if (tree->opval.op==LEFT_OP ||
-             (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
-           lineno=tree->lineno;
-           werror (W_SHIFT_CHANGED,
-                   (tree->opval.op == LEFT_OP ? "left" : "right"));
-           tree->type = EX_VALUE;
-           tree->left = tree->right = NULL;
-           tree->opval.val = constVal ("0");
-           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
-           return tree;
-         }
+             (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
+           {
+             lineno=tree->lineno;
+             werror (W_SHIFT_CHANGED,
+                     (tree->opval.op == LEFT_OP ? "left" : "right"));
+             tree->type = EX_VALUE;
+             tree->left = tree->right = NULL;
+             tree->opval.val = constVal ("0");
+             TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
+             return tree;
+           }
        }
-      LRVAL (tree) = RRVAL (tree) = 1;
-      TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
-      if (IS_LITERAL (TTYPE (tree)))
-        SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
+
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -3173,6 +3233,23 @@ decorateType (ast * tree)
       /* make sure the type is complete and sane */
       checkTypeSanity(LETYPE(tree), "(cast)");
 
+      /* If code memory is read only, then pointers to code memory */
+      /* implicitly point to constants -- make this explicit       */
+      {
+       sym_link *t = LTYPE(tree);
+       while (t && t->next)
+         {
+           if (IS_CODEPTR(t) && port->mem.code_ro)
+             {
+               if (IS_SPEC(t->next))
+                 SPEC_CONST (t->next) = 1;
+               else
+                 DCL_PTR_CONST (t->next) = 1;
+             }
+           t = t->next;
+          }
+      }
+
 #if 0
       /* if the right is a literal replace the tree */
       if (IS_LITERAL (RETYPE (tree))) {
@@ -3262,7 +3339,8 @@ decorateType (ast * tree)
 
       /* if the right is a literal replace the tree */
       if (IS_LITERAL (RETYPE (tree))) {
-        if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
+        #if 0
+       if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
           /* rewrite      (type *)litaddr
              as           &temp
              and define   type at litaddr temp
@@ -3299,6 +3377,7 @@ decorateType (ast * tree)
           TLVAL (newTree) = 1;
           return newTree;
         }
+       #endif
         if (!IS_PTR (LTYPE (tree))) {
          tree->type = EX_VALUE;
          tree->opval.val =
@@ -3416,17 +3495,27 @@ decorateType (ast * tree)
              }
        }
       /* if unsigned value < 0  then always false */
-      /* if (unsigned value) > 0 then (unsigned value) */
-      if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  && 
-         ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
-
-         if (tree->opval.op == '<') {
+      /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
+      if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  &&
+         ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
+       {
+         if (tree->opval.op == '<')
+           {
              return tree->right;
-         }
-         if (tree->opval.op == '>') {
-             return tree->left;
-         }
-      }
+           }
+         if (tree->opval.op == '>')
+           {
+             /* if the parent is an ifx, then we could do */
+             /* return tree->left; */
+             tree->opval.op = '?';
+             tree->right = newNode (':',
+                                    newAst_VALUE (constVal ("1")),
+                                    tree->right); /* val 0 */
+             tree->right->lineno = tree->lineno;
+             tree->right->left->lineno = tree->lineno;
+             decorateType (tree->right);
+           }
+        }
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) &&
@@ -3565,7 +3654,7 @@ decorateType (ast * tree)
          goto errorTreeReturn;
        }
 
-      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
+      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
       TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
@@ -3647,7 +3736,8 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           FALSE));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "-=");
@@ -3688,7 +3778,8 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
-                                           RTYPE (tree)));
+                                           RTYPE (tree),
+                                           FALSE));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "+=");
@@ -3793,7 +3884,7 @@ decorateType (ast * tree)
 
       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
        {
-         werror (W_RETURN_MISMATCH);
+         werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
          printFromToType (RTYPE(tree), currFunc->type->next);
          goto errorTreeReturn;
        }
@@ -3802,7 +3893,7 @@ decorateType (ast * tree)
          && tree->right &&
          !IS_VOID (RTYPE (tree)))
        {
-         werror (E_FUNC_VOID);
+         werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
          goto errorTreeReturn;
        }
 
@@ -3837,7 +3928,7 @@ decorateType (ast * tree)
       /* the switch value must be an integer */
       if (!IS_INTEGRAL (LTYPE (tree)))
        {
-         werror (E_SWITCH_NON_INTEGER);
+         werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
          goto errorTreeReturn;
        }
       LRVAL (tree) = 1;
@@ -4094,7 +4185,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
   /* then case is out of context            */
   if (!swStat)
     {
-      werror (E_CASE_CONTEXT);
+      werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
       return NULL;
     }
 
@@ -4102,14 +4193,14 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
   /* if not a constant then error  */
   if (!IS_LITERAL (caseVal->ftype))
     {
-      werror (E_CASE_CONSTANT);
+      werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
       return NULL;
     }
 
   /* if not a integer than error */
   if (!IS_INTEGRAL (caseVal->ftype))
     {
-      werror (E_CASE_NON_INTEGER);
+      werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
       return NULL;
     }
 
@@ -4132,6 +4223,12 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
        {
          pval->next = caseVal->opval.val;
        }
+      else if ((int) floatFromVal (val) == cVal)
+       {
+         werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
+                   "case");
+         return NULL;
+       }
       else
        {
          /* we found a value greater than */
@@ -4164,7 +4261,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
 /* createDefault - creates the parse tree for the default statement */
 /*-----------------------------------------------------------------*/
 ast *
-createDefault (ast * swStat, ast * stmnt)
+createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
 {
   char defLbl[SDCC_NAME_MAX + 1];
 
@@ -4172,7 +4269,14 @@ createDefault (ast * swStat, ast * stmnt)
   /* then case is out of context            */
   if (!swStat)
     {
-      werror (E_CASE_CONTEXT);
+      werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
+      return NULL;
+    }
+
+  if (swStat->values.switchVals.swDefault)
+    {
+      werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
+               "default");
       return NULL;
     }
 
@@ -5085,7 +5189,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                                fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
                        else
                                fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
-                       fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
+                       fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
                                                      floatFromVal(tree->opval.val));
                } else if (tree->opval.val->sym) {
                        /* if the undefined flag is set then give error message */
@@ -5479,7 +5583,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                ast_print(tree->left,outfile,indent+2);
                ast_print(tree->right,outfile,indent+2);
                return ;
-               
+
                /*------------------------------------------------------------------*/
                /*----------------------------*/
                /*    assignment operators    */