* device/include/Makefile.in: fix install
[fw/sdcc] / src / SDCCast.c
index 354a70b2e99e0dbed33c6c9ddf7594e1ebe3f3f2..15f92a760e34a7147bb041efeff3b514693915c9 100644 (file)
@@ -84,6 +84,7 @@ newAst_ (unsigned type)
   ex->level = NestLevel;
   ex->block = currBlockno;
   ex->initMode = inInitMode;
+  ex->seqPoint = seqPointNo;
   return ex;
 }
 
@@ -273,6 +274,52 @@ ast *removeIncDecOps (ast * tree) {
  return tree;
 }
 
+/*-----------------------------------------------------------------*/
+/* removePreIncDecOps: remove for side effects in *_ASSIGN's       */
+/*                  "*++s += 3" -> "*++s = *++s + 3"               */
+/*-----------------------------------------------------------------*/
+ast *removePreIncDecOps (ast * tree) {
+
+  // traverse the tree and remove pre-inc/dec ops
+
+  if (!tree)
+    return NULL;
+
+  if (tree->type == EX_OP &&
+      (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
+    if (tree->right)
+      tree=tree->right;
+  }
+
+  tree->left=removePreIncDecOps(tree->left);
+  tree->right=removePreIncDecOps(tree->right);
+
+ return tree;
+}
+
+/*-----------------------------------------------------------------*/
+/* removePostIncDecOps: remove for side effects in *_ASSIGN's      */
+/*                  "*s++ += 3" -> "*s++ = *s++ + 3"               */
+/*-----------------------------------------------------------------*/
+ast *removePostIncDecOps (ast * tree) {
+
+  // traverse the tree and remove pre-inc/dec ops
+
+  if (!tree)
+    return NULL;
+
+  if (tree->type == EX_OP &&
+      (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
+    if (tree->left)
+      tree=tree->left;
+  }
+
+  tree->left=removePostIncDecOps(tree->left);
+  tree->right=removePostIncDecOps(tree->right);
+
+ return tree;
+}
+
 /*-----------------------------------------------------------------*/
 /* hasSEFcalls - returns TRUE if tree has a function call          */
 /*-----------------------------------------------------------------*/
@@ -297,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)
@@ -383,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)
@@ -393,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);
        }
 
     }
@@ -408,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;
 
@@ -447,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
@@ -624,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;
     }
@@ -811,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;
@@ -872,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
@@ -897,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;
            }
@@ -939,8 +994,18 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
       /* to the array element */
       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;
+       }
 
-      while (*s)
+      for (i=0;i<size;i++)
        {
          rast = newNode (NULLOP,
                          rast,
@@ -948,15 +1013,8 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
                                   newNode ('[', sym,
                                   newAst_VALUE (valueFromLit ((float) i))),
                                   newAst_VALUE (valueFromLit (*s))));
-         i++;
          s++;
        }
-      rast = newNode (NULLOP,
-                     rast,
-                     newNode ('=',
-                              newNode ('[', sym,
-                                  newAst_VALUE (valueFromLit ((float) i))),
-                              newAst_VALUE (valueFromLit (*s))));
 
       // now WE don't need iexpr's symbol anymore
       freeStringSymbol(AST_SYMBOL(iexpr));
@@ -1068,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));
@@ -1103,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));
@@ -1148,12 +1208,14 @@ stringToSymbol (value * val)
   static int charLbl = 0;
   symbol *sym;
   set *sp;
+  int size;
 
   // have we heard this before?
   for (sp=statsg->syms; sp; sp=sp->next) {
     sym=sp->item;
-    if (sym->isstrlit && 
-       !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
+    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);
@@ -1532,7 +1594,7 @@ astHasSymbol (ast * tree, symbol * sym)
       else
        return FALSE;
     }
-  
+
   return astHasSymbol (tree->left, sym) ||
     astHasSymbol (tree->right, sym);
 }
@@ -2047,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 */
@@ -2196,6 +2280,10 @@ decorateType (ast * tree)
        break;
       }
       
+      /* This breaks with extern declarations, bitfields, and perhaps other */
+      /* cases (gcse). Let's leave this optimization disabled for now and   */
+      /* ponder if there's a safe way to do this. -- EEP                    */
+      #if 0
       if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
           && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
         {
@@ -2228,7 +2316,8 @@ decorateType (ast * tree)
             tree->left = NULL;
             tree->right = NULL;
         }
-
+      #endif
+      
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2293,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 */
@@ -2337,7 +2426,7 @@ decorateType (ast * tree)
          goto errorTreeReturn;
        }
 
-      if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
+      if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
        {
          werror (E_ILLEGAL_ADDR, "address of register variable");
          goto errorTreeReturn;
@@ -2360,7 +2449,9 @@ decorateType (ast * tree)
          werror (E_LVALUE_REQUIRED, "address of");
          goto errorTreeReturn;
        }
-      if (SPEC_SCLS (tree->left->etype) == S_CODE)
+      if (!LETYPE (tree))
+        DCL_TYPE (p) = POINTER;
+      else if (SPEC_SCLS (tree->left->etype) == S_CODE)
        DCL_TYPE (p) = CPOINTER;
       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
        DCL_TYPE (p) = FPOINTER;
@@ -2418,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 */
@@ -2446,6 +2535,8 @@ decorateType (ast * tree)
              decorateType (parent);
            }
         }
+      /* fall through */
+
       /*------------------------------------------------------------------*/
       /*----------------------------*/
       /*  bitwise xor               */
@@ -2487,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, "^");
@@ -2504,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;
 
       /*------------------------------------------------------------------*/
       /*----------------------------*/
@@ -2532,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 */
@@ -2597,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;
 
       /*------------------------------------------------------------------*/
@@ -2709,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;
 
@@ -2727,7 +2819,7 @@ decorateType (ast * tree)
       /* if unary plus */
       if (!tree->right)
        {
-         if (!IS_INTEGRAL (LTYPE (tree)))
+         if (!IS_ARITHMETIC (LTYPE (tree)))
            {
              werror (E_UNARY_OP, '+');
              goto errorTreeReturn;
@@ -2846,7 +2938,8 @@ decorateType (ast * tree)
       else
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 computeType (LTYPE (tree),
-                                             RTYPE (tree)));
+                                             RTYPE (tree),
+                                             FALSE));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2945,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;
 
@@ -3085,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;
 
       /*------------------------------------------------------------------*/
@@ -3200,7 +3309,7 @@ decorateType (ast * tree)
          tree->opval.val = valCastLiteral (
            LTYPE (tree),
            element->offset
-            + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
+            + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
           );
 
          TTYPE (tree) = tree->opval.val->type;
@@ -3236,7 +3345,7 @@ decorateType (ast * tree)
           sym->cdef = 1;
           sym->isref = 1;
           SPEC_STAT (sym->etype) = 1;
-          SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
+          SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
           SPEC_ABSA(sym->etype) = 1;
           addSym (SymbolTab, sym, sym->name, 0, 0, 0);
           allocGlobal (sym);
@@ -3254,7 +3363,7 @@ decorateType (ast * tree)
          tree->type = EX_VALUE;
          tree->opval.val =
          valCastLiteral (LTYPE (tree),
-                         floatFromVal (valFromType (RETYPE (tree))));
+                         floatFromVal (valFromType (RTYPE (tree))));
          TTYPE (tree) = tree->opval.val->type;
          tree->left = NULL;
          tree->right = NULL;
@@ -3299,8 +3408,8 @@ decorateType (ast * tree)
          IS_LITERAL (LTYPE (tree)))
        {
          tree->type = EX_VALUE;
-         tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
-                                          valFromType (RETYPE (tree)),
+         tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
+                                          valFromType (RTYPE (tree)),
                                           tree->opval.op);
          tree->right = tree->left = NULL;
          TETYPE (tree) = getSpec (TTYPE (tree) =
@@ -3341,7 +3450,7 @@ decorateType (ast * tree)
          if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
            {
              werror (E_COMPARE_OP);
-             fprintf (stderr, "comparring type ");
+             fprintf (stderr, "comparing type ");
              printTypeChain (LTYPE (tree), stderr);
              fprintf (stderr, "to type ");
              printTypeChain (RTYPE (tree), stderr);
@@ -3368,16 +3477,18 @@ 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 (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 == '>') {
+           }
+         if (tree->opval.op == '>')
+           {
              return tree->left;
-         }
-      }
+           }
+        }
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) &&
@@ -3516,7 +3627,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;
 
@@ -3539,11 +3650,11 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
 
       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
-       werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
+       werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
 
       if (LRVAL (tree))
        {
-         werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
+         werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
          goto errorTreeReturn;
        }
       LLVAL (tree) = 1;
@@ -3598,7 +3709,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, "-=");
@@ -3639,7 +3751,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, "+=");
@@ -3744,7 +3857,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;
        }
@@ -3753,7 +3866,7 @@ decorateType (ast * tree)
          && tree->right &&
          !IS_VOID (RTYPE (tree)))
        {
-         werror (E_FUNC_VOID);
+         werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
          goto errorTreeReturn;
        }
 
@@ -3788,7 +3901,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;
@@ -4045,7 +4158,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;
     }
 
@@ -4053,14 +4166,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;
     }
 
@@ -4083,6 +4196,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 */
@@ -4115,7 +4234,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];
 
@@ -4123,7 +4242,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;
     }
 
@@ -5036,7 +5162,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 */
@@ -5648,3 +5774,29 @@ void PA(ast *t)
 {
        ast_print(t,stdout,0);
 }
+
+
+
+/*-----------------------------------------------------------------*/
+/* astErrors : returns non-zero if errors present in tree          */
+/*-----------------------------------------------------------------*/
+int astErrors(ast *t)
+{
+  int errors=0;
+  
+  if (t)
+    {
+      if (t->isError)
+        errors++;
+  
+      if (t->type == EX_VALUE
+          && t->opval.val->sym
+          && t->opval.val->sym->undefined)
+        errors++;
+
+      errors += astErrors(t->left);
+      errors += astErrors(t->right);
+    }
+    
+  return errors;
+}