missing return values is a warning now
[fw/sdcc] / src / SDCCast.c
index cd93f35b4f4173b883b0006b587c5d19843a4fe7..91a4f81e08fe35e461a888234810291af6c47aa9 100644 (file)
@@ -47,9 +47,10 @@ int labelKey = 1;
 
 int noLineno = 0;
 int noAlloc = 0;
-symbol *currFunc;
+symbol *currFunc=NULL;
 static ast *createIval (ast *, sym_link *, initList *, ast *);
 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
+static ast *optimizeCompare (ast *);
 ast *optimizeRRCRLC (ast *);
 ast *optimizeGetHbit (ast *);
 ast *backPatchLabels (ast *, symbol *, symbol *);
@@ -185,8 +186,7 @@ copyAstValues (ast * dest, ast * src)
       break;
 
     case INLINEASM:
-      dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
-      strcpy (dest->values.inlineasm, src->values.inlineasm);
+      dest->values.inlineasm =  Safe_strdup(src->values.inlineasm);
       break;
 
     case ARRAYINIT:
@@ -209,7 +209,7 @@ copyAstValues (ast * dest, ast * src)
 /* copyAst - makes a copy of a given astession                     */
 /*-----------------------------------------------------------------*/
 ast *
-copyAst (ast * src)
+copyAst (ast * src) 
 {
   ast *dest;
 
@@ -255,6 +255,31 @@ exit:
 
 }
 
+/*-----------------------------------------------------------------*/
+/* removeIncDecOps: remove for side effects in *_ASSIGN's          */
+/*                  "*s++ += 3" -> "*s++ = *s++ + 3"               */
+/*-----------------------------------------------------------------*/
+ast *removeIncDecOps (ast * tree) {
+
+  // traverse the tree and remove 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;
+    else 
+      tree=tree->right;
+  }
+
+  tree->left=removeIncDecOps(tree->left);
+  tree->right=removeIncDecOps(tree->right);
+ return tree;
+}
+
 /*-----------------------------------------------------------------*/
 /* hasSEFcalls - returns TRUE if tree has a function call          */
 /*-----------------------------------------------------------------*/
@@ -341,6 +366,7 @@ resolveSymbols (ast * tree)
   if (tree == NULL)
     return tree;
 
+#if 0
   /* print the line          */
   /* if not block & function */
   if (tree->type == EX_OP &&
@@ -351,6 +377,7 @@ resolveSymbols (ast * tree)
       filename = tree->filename;
       lineno = tree->lineno;
     }
+#endif
 
   /* make sure we resolve the true & false labels for ifx */
   if (tree->type == EX_OP && tree->opval.op == IFX)
@@ -421,7 +448,7 @@ resolveSymbols (ast * tree)
          /* mark it as returning an int     */
          if (tree->funcName)
            {
-             tree->opval.val->sym->type = newLink ();
+             tree->opval.val->sym->type = newLink (DECLARATOR);
              DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
              tree->opval.val->sym->type->next =
                tree->opval.val->sym->etype = newIntLink ();
@@ -451,8 +478,7 @@ resolveChildren:
 /*-----------------------------------------------------------------*/
 /* setAstLineno - walks a ast tree & sets the line number          */
 /*-----------------------------------------------------------------*/
-int 
-setAstLineno (ast * tree, int lineno)
+int setAstLineno (ast * tree, int lineno)
 {
   if (!tree)
     return 0;
@@ -475,11 +501,11 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
   sym = newSymbol (name, 0);
 
   /* setup return value */
-  sym->type = newLink ();
+  sym->type = newLink (DECLARATOR);
   DCL_TYPE (sym->type) = FUNCTION;
   sym->type->next = copyLinkChain (type);
   sym->etype = getSpec (sym->type);
-  FUNC_ISREENT(sym->type) = rent;
+  FUNC_ISREENT(sym->type) = rent ? 1 : 0;
 
   /* if arguments required */
   if (nArgs)
@@ -519,7 +545,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
     sym = newSymbol (name, 0);
     
     /* setup return value */
-    sym->type = newLink ();
+    sym->type = newLink (DECLARATOR);
     DCL_TYPE (sym->type) = FUNCTION;
     sym->type->next = typeFromStr(rtype);
     sym->etype = getSpec (sym->type);
@@ -640,7 +666,20 @@ processParms (ast * func,
       if (IS_INTEGRAL (ftype)
          && (getSize (ftype) < (unsigned) INTSIZE))
        {
-         newType = newAst_LINK(INTTYPE);
+         if (IS_AST_OP(actParm) && 
+             (actParm->opval.op == LEFT_OP ||
+              actParm->opval.op == '*' ||
+              actParm->opval.op == '+' ||
+              actParm->opval.op == '-') &&
+             actParm->right) {
+           // we should cast an operand instead of the result
+           actParm->decorated = 0;
+           actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
+                                        actParm->left);
+           actParm = decorateType(actParm);
+         } else {
+           newType = newAst_LINK(INTTYPE);
+         }
        }
 
       if (IS_PTR(ftype) && !IS_GENPTR(ftype))
@@ -727,6 +766,7 @@ processParms (ast * func,
   /* make a copy and change the regparm type to the defined parm */
   actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
   SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
+  SPEC_ARGREG  (actParm->etype) = SPEC_ARGREG (defParm->etype);
   (*parmNumber)++;
   return 0;
 }
@@ -924,6 +964,10 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
                               newNode ('[', sym,
                                   newAst_VALUE (valueFromLit ((float) i))),
                               newAst_VALUE (valueFromLit (*s))));
+
+      // now WE don't need iexpr's symbol anymore
+      freeStringSymbol(AST_SYMBOL(iexpr));
+
       return decorateType (resolveSymbols (rast));
     }
 
@@ -1052,6 +1096,16 @@ gatherAutoInit (symbol * autoChain)
       /* if there is an initial value */
       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
        {
+         initList *ilist=sym->ival;
+         
+         while (ilist->type == INIT_DEEP) {
+           ilist = ilist->init.deep;
+         }
+
+         /* update lineno for error msg */
+         lineno=sym->lineDef;
+         setAstLineno (ilist->init.node, lineno);
+         
          if (IS_AGGREGATE (sym->type)) {
            work = initAggregates (sym, sym->ival, NULL);
          } else {
@@ -1062,8 +1116,10 @@ gatherAutoInit (symbol * autoChain)
            work = newNode ('=', newAst_VALUE (symbolVal (sym)),
                            list2expr (sym->ival));
          }
-
+         
+         // just to be sure
          setAstLineno (work, sym->lineDef);
+
          sym->ival = NULL;
          if (init)
            init = newNode (NULLOP, init, work);
@@ -1075,6 +1131,20 @@ gatherAutoInit (symbol * autoChain)
   return init;
 }
 
+/*-----------------------------------------------------------------*/
+/* freeStringSymbol - delete a literal string if no more usage     */
+/*-----------------------------------------------------------------*/
+void freeStringSymbol(symbol *sym) {
+  /* make sure this is a literal string */
+  assert (sym->isstrlit);
+  if (--sym->isstrlit == 0) { // lower the usage count
+    memmap *segment=SPEC_OCLS(sym->etype);
+    if (segment) {
+      deleteSetItem(&segment->syms, sym);
+    }
+  }
+}
+  
 /*-----------------------------------------------------------------*/
 /* stringToSymbol - creates a symbol from a literal string         */
 /*-----------------------------------------------------------------*/
@@ -1084,10 +1154,22 @@ stringToSymbol (value * val)
   char name[SDCC_NAME_MAX + 1];
   static int charLbl = 0;
   symbol *sym;
+  set *sp;
+
+  // 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)) {
+      // yes, this is old news. Don't publish it again.
+      sym->isstrlit++; // but raise the usage count
+      return symbolVal(sym);
+    }
+  }
 
-  sprintf (name, "_str_%d", charLbl++);
+  SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
   sym = newSymbol (name, 0);   /* make it @ level 0 */
-  strcpy (sym->rname, name);
+  strncpyz (sym->rname, name, SDCC_NAME_MAX);
 
   /* copy the type from the value passed */
   sym->type = copyLinkChain (val->type);
@@ -1129,14 +1211,14 @@ processBlockVars (ast * tree, int *stack, int action)
       ast *autoInit;
 
       if (action == ALLOCATE)
-       {
+        {
          *stack += allocVariables (tree->values.sym);
          autoInit = gatherAutoInit (tree->values.sym);
-
+       
          /* if there are auto inits then do them */
          if (autoInit)
            tree->left = newNode (NULLOP, autoInit, tree->left);
-       }
+        }
       else                     /* action is deallocate */
        deallocLocal (tree->values.sym);
     }
@@ -1146,6 +1228,69 @@ processBlockVars (ast * tree, int *stack, int action)
   return tree;
 }
 
+/*-------------------------------------------------------------*/
+/* constExprTree - returns TRUE if this tree is a constant     */
+/*                 expression                                  */
+/*-------------------------------------------------------------*/
+bool constExprTree (ast *cexpr) {
+
+  if (!cexpr) {
+    return TRUE;
+  }
+
+  cexpr = decorateType (resolveSymbols (cexpr));
+  
+  switch (cexpr->type) 
+    {
+    case EX_VALUE:
+      if (IS_AST_LIT_VALUE(cexpr)) {
+       // this is a literal
+       return TRUE;
+      }
+      if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
+       // a function's address will never change
+       return TRUE;
+      }
+      if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
+       // an array's address will never change
+       return TRUE;
+      }
+      if (IS_AST_SYM_VALUE(cexpr) && 
+         IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
+       // a symbol in code space will never change
+       // This is only for the 'char *s="hallo"' case and will have to leave
+       return TRUE;
+      }
+      return FALSE;
+    case EX_LINK:
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             "unexpected link in expression tree\n");
+      return FALSE;
+    case EX_OP:
+      if (cexpr->opval.op==ARRAYINIT) {
+       // this is a list of literals
+       return TRUE;
+      }
+      if (cexpr->opval.op=='=') {
+       return constExprTree(cexpr->right);
+      }
+      if (cexpr->opval.op==CAST) {
+       // cast ignored, maybe we should throw a warning here?
+       return constExprTree(cexpr->right);
+      }
+      if (cexpr->opval.op=='&') { 
+       return TRUE;
+      }
+      if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
+       return FALSE;
+      }
+      if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
+       return TRUE;
+      }
+    }
+  return FALSE;
+}  
+    
 /*-----------------------------------------------------------------*/
 /* constExprValue - returns the value of a constant expression     */
 /*                  or NULL if it is not a constant expression     */
@@ -1169,16 +1314,16 @@ constExprValue (ast * cexpr, int check)
          val->sym = cexpr->opval.val->sym;
          val->sym->type = copyLinkChain (cexpr->ftype);
          val->sym->etype = getSpec (val->sym->type);
-         strcpy (val->name, cexpr->opval.val->sym->rname);
+         strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
          return val;
        }
 
       /* if we are casting a literal value then */
       if (IS_AST_OP (cexpr) &&
          cexpr->opval.op == CAST &&
-         IS_LITERAL (cexpr->left->ftype))
+         IS_LITERAL (cexpr->right->ftype))
        return valCastLiteral (cexpr->ftype,
-                              floatFromVal (cexpr->left->opval.val));
+                              floatFromVal (cexpr->right->opval.val));
 
       if (IS_AST_VALUE (cexpr))
        return cexpr->opval.val;
@@ -1427,8 +1572,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
   /* if we reach the end or a leaf then true */
   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
     return TRUE;
-
-
+  
   /* if anything else is "volatile" */
   if (IS_VOLATILE (TETYPE (pbody)))
     return FALSE;
@@ -1439,6 +1583,10 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
     {
 /*------------------------------------------------------------------*/
     case '[':
+      // if the loopvar is used as an index
+      if (astHasSymbol(pbody->right, sym)) {
+       return FALSE;
+      }
       return isConformingBody (pbody->right, sym, body);
 
 /*------------------------------------------------------------------*/
@@ -1548,9 +1696,16 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
       if (astHasVolatile (pbody->left))
        return FALSE;
 
-      if (IS_AST_SYM_VALUE (pbody->left) &&
-         isSymbolEqual (AST_SYMBOL (pbody->left), sym))
-       return FALSE;
+      if (IS_AST_SYM_VALUE (pbody->left)) {
+       // if the loopvar has an assignment
+       if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
+         return FALSE;
+       // if the loopvar is used in another (maybe conditional) block
+       if (astHasSymbol (pbody->right, sym) &&
+           (pbody->level > body->level)) {
+         return FALSE;
+       }
+      }
 
       if (astHasVolatile (pbody->left))
        return FALSE;
@@ -1584,6 +1739,9 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
       /*       function call        */
 /*----------------------------*/
     case CALL:
+       /* if local & not passed as paramater then ok */
+       if (sym->level && !astHasSymbol(pbody->right,sym)) 
+           return TRUE;
       return FALSE;
 
 /*------------------------------------------------------------------*/
@@ -1697,14 +1855,15 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
   rloop = newNode (NULLOP,
                   createIf (newAst_VALUE (symbolVal (sym)),
                             newNode (GOTO,
-                  newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
+                                     newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
                                      NULL), NULL),
                   newNode ('=',
                            newAst_VALUE (symbolVal (sym)),
                            end));
-
+  
   replLoopSym (loop->left, sym);
-
+  setAstLineno (rloop, init->lineno);
+  
   rloop = newNode (NULLOP,
                   newNode ('=',
                            newAst_VALUE (symbolVal (sym)),
@@ -1714,12 +1873,13 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
                                         loop->left,
                                         newNode (NULLOP,
                                                  newNode (SUB_ASSIGN,
-                                            newAst_VALUE (symbolVal (sym)),
-                                            newAst_VALUE (constVal ("1"))),
+                                                          newAst_VALUE (symbolVal (sym)),
+                                                          newAst_VALUE (constVal ("1"))),
                                                  rloop))));
-
+  
+  rloop->lineno=init->lineno;
   return decorateType (rloop);
-
+  
 }
 
 /*-----------------------------------------------------------------*/
@@ -1742,6 +1902,7 @@ decorateType (ast * tree)
 
   tree->decorated = 1;
 
+#if 0
   /* print the line          */
   /* if not block & function */
   if (tree->type == EX_OP &&
@@ -1752,6 +1913,7 @@ decorateType (ast * tree)
       filename = tree->filename;
       lineno = tree->lineno;
     }
+#endif
 
   /* if any child is an error | this one is an error do nothing */
   if (tree->isError ||
@@ -1763,6 +1925,7 @@ decorateType (ast * tree)
 /*----------------------------*/
   /*   leaf has been reached    */
 /*----------------------------*/
+  lineno=tree->lineno;
   /* if this is of type value */
   /* just get the type        */
   if (tree->type == EX_VALUE)
@@ -1835,16 +1998,36 @@ decorateType (ast * tree)
       tree->left = dtl;
     if (dtr != tree->right)
       tree->right = dtr;
+
+    if (IS_AST_OP(tree) &&
+       (tree->opval.op == CAST || tree->opval.op == '=') &&
+       (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
+       (getSize(RTYPE(tree)) < INTSIZE)) {
+      // this is a cast/assign to a bigger type
+      if (IS_AST_OP(tree->right) &&
+         IS_INTEGRAL(tree->right->ftype) &&
+         (tree->right->opval.op == LEFT_OP ||
+          tree->right->opval.op == '*' ||
+          tree->right->opval.op == '+' ||
+          tree->right->opval.op == '-') &&
+         tree->right->right) {
+       // we should cast an operand instead of the result
+       tree->right->decorated = 0;
+       tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
+                                    tree->right->left);
+       tree->right = decorateType(tree->right);
+      }
+    }
   }
 
   /* depending on type of operator do */
 
   switch (tree->opval.op)
     {
-           /*------------------------------------------------------------------*/
-           /*----------------------------*/
-           /*        array node          */
-           /*----------------------------*/
+       /*------------------------------------------------------------------*/
+       /*----------------------------*/
+       /*        array node          */
+       /*----------------------------*/
     case '[':
 
       /* determine which is the array & which the index */
@@ -1879,7 +2062,7 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
       if (IS_PTR(LTYPE(tree))) {
-             SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
+       SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
       }
       return tree;
 
@@ -1906,7 +2089,7 @@ decorateType (ast * tree)
       /*----------------------------*/
     case PTR_OP:
       /* if not pointer to a structure */
-      if (!IS_PTR (LTYPE (tree)))
+      if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
        {
          werror (E_PTR_REQD);
          goto errorTreeReturn;
@@ -1947,21 +2130,22 @@ decorateType (ast * tree)
       case UPOINTER:
       case ARRAY:
       case FUNCTION:
+       break;
       }
 
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*  ++/-- operation           */
-/*----------------------------*/
+      /*----------------------------*/
     case INC_OP:               /* incerement operator unary so left only */
     case DEC_OP:
       {
        sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
        COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
        if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
-         werror (E_CODE_WRITE, "++/--");
+         werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
 
        if (tree->right)
          RLVAL (tree) = 1;
@@ -1970,10 +2154,10 @@ decorateType (ast * tree)
        return tree;
       }
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*  bitwise and               */
-/*----------------------------*/
+      /*----------------------------*/
     case '&':                  /* can be unary   */
       /* if right is NULL then unary operation  */
       if (tree->right)         /* not an unary operation */
@@ -2020,12 +2204,11 @@ decorateType (ast * tree)
          return tree;
        }
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*  address of                */
-/*----------------------------*/
-      p = newLink ();
-      p->class = DECLARATOR;
+      /*----------------------------*/
+      p = newLink (DECLARATOR);
       /* if bit field then error */
       if (IS_BITVAR (tree->left->etype))
        {
@@ -2041,8 +2224,8 @@ decorateType (ast * tree)
 
       if (IS_FUNC (LTYPE (tree)))
        {
-         werror (E_ILLEGAL_ADDR, "address of function");
-         goto errorTreeReturn;
+         // this ought to be ignored
+         return (tree->left);
        }
 
       if (IS_LITERAL(LTYPE(tree)))
@@ -2083,27 +2266,28 @@ decorateType (ast * tree)
       p->next = LTYPE (tree);
       TTYPE (tree) = p;
       TETYPE (tree) = getSpec (TTYPE (tree));
-      DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
-      DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
+      DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));   
+      DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree)); 
       LLVAL (tree) = 1;
       TLVAL (tree) = 1;
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*  bitwise or                */
-/*----------------------------*/
+      /*----------------------------*/
     case '|':
       /* if the rewrite succeeds then don't go any furthur */
       {
        ast *wtree = optimizeRRCRLC (tree);
        if (wtree != tree)
          return decorateType (wtree);
+       // fall through
       }
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*  bitwise xor               */
-/*----------------------------*/
+      /*----------------------------*/
     case '^':
       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
        {
@@ -2134,10 +2318,10 @@ decorateType (ast * tree)
                               computeType (LTYPE (tree),
                                            RTYPE (tree)));
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*  division                  */
-/*----------------------------*/
+      /*----------------------------*/
     case '/':
       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
        {
@@ -2162,10 +2346,10 @@ decorateType (ast * tree)
                                            RTYPE (tree)));
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*            modulus         */
-/*----------------------------*/
+      /*----------------------------*/
     case '%':
       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
        {
@@ -2195,10 +2379,10 @@ decorateType (ast * tree)
                                            RTYPE (tree)));
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
-/*  address dereference       */
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
+      /*  address dereference       */
+      /*----------------------------*/
     case '*':                  /* can be unary  : if right is null then unary operation */
       if (!tree->right)
        {
@@ -2213,17 +2397,16 @@ decorateType (ast * tree)
              werror (E_LVALUE_REQUIRED, "pointer deref");
              goto errorTreeReturn;
            }
-         TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
-                                       LTYPE (tree)->next : NULL);
+         TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
          TETYPE (tree) = getSpec (TTYPE (tree));
          SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
          return tree;
        }
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      multiplication        */
-/*----------------------------*/
+      /*----------------------------*/
       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
        {
          werror (E_INVALID_OP, "multiplication");
@@ -2252,24 +2435,22 @@ 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))) {
-       TETYPE (tree) = getSpec (TTYPE (tree) =
-                                computeType (LTYPE (tree),
-                                             RTYPE (tree)));
        SPEC_NOUN(TETYPE(tree)) = V_INT;
-      } else {
-       TETYPE (tree) = getSpec (TTYPE (tree) =
-                                computeType (LTYPE (tree),
-                                             RTYPE (tree)));
       }
+
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*    unary '+' operator      */
-/*----------------------------*/
+      /*----------------------------*/
     case '+':
       /* if unary plus */
       if (!tree->right)
@@ -2294,10 +2475,10 @@ decorateType (ast * tree)
          return tree;
        }
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      addition              */
-/*----------------------------*/
+      /*----------------------------*/
 
       /* this is not a unary operation */
       /* if both pointers then problem */
@@ -2347,7 +2528,7 @@ decorateType (ast * tree)
 
       LRVAL (tree) = RRVAL (tree) = 1;
       /* if the left is a pointer */
-      if (IS_PTR (LTYPE (tree)))
+      if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 LTYPE (tree));
       else
@@ -2356,10 +2537,10 @@ decorateType (ast * tree)
                                              RTYPE (tree)));
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      unary '-'             */
-/*----------------------------*/
+      /*----------------------------*/
     case '-':                  /* can be unary   */
       /* if right is null then unary */
       if (!tree->right)
@@ -2382,14 +2563,14 @@ decorateType (ast * tree)
              return tree;
            }
          LRVAL (tree) = 1;
-         TTYPE (tree) = LTYPE (tree);
+         TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
          return tree;
        }
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*    subtraction             */
-/*----------------------------*/
+      /*----------------------------*/
 
       if (!(IS_PTR (LTYPE (tree)) ||
            IS_ARRAY (LTYPE (tree)) ||
@@ -2456,10 +2637,10 @@ decorateType (ast * tree)
       LRVAL (tree) = RRVAL (tree) = 1;
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*    compliment              */
-/*----------------------------*/
+      /*----------------------------*/
     case '~':
       /* can be only integral type */
       if (!IS_INTEGRAL (LTYPE (tree)))
@@ -2481,10 +2662,10 @@ decorateType (ast * tree)
       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*           not              */
-/*----------------------------*/
+      /*----------------------------*/
     case '!':
       /* can be pointer */
       if (!IS_ARITHMETIC (LTYPE (tree)) &&
@@ -2508,10 +2689,10 @@ decorateType (ast * tree)
       TTYPE (tree) = TETYPE (tree) = newCharLink ();
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*           shift            */
-/*----------------------------*/
+      /*----------------------------*/
     case RRC:
     case RLC:
       TTYPE (tree) = LTYPE (tree);
@@ -2548,19 +2729,24 @@ decorateType (ast * tree)
                                   tree->opval.val->type);
          return tree;
        }
+
       /* 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))
        {
-         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;
+         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;
+         }
        }
       LRVAL (tree) = RRVAL (tree) = 1;
       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
@@ -2604,7 +2790,7 @@ decorateType (ast * tree)
                         ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
                      sym_link *rest = LTYPE(tree)->next;
                      werror(W_LITERAL_GENERIC);                      
-                     TTYPE(tree) = newLink();
+                     TTYPE(tree) = newLink(DECLARATOR);
                      DCL_TYPE(TTYPE(tree)) = FPOINTER;
                      TTYPE(tree)->next = rest;
                      tree->left->opval.lnk = TTYPE(tree);
@@ -2618,12 +2804,16 @@ decorateType (ast * tree)
              LRVAL (tree) = 1;
       }
 #else
+#if 0 // this is already checked, now this could be explicit
       /* if pointer to struct then check names */
       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
          IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
-         strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
-             werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
-      }
+         strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) 
+       {
+         werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
+                SPEC_STRUCT(LETYPE(tree))->tag);
+       }
+#endif
       /* if the right is a literal replace the tree */
       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
        tree->type = EX_VALUE;
@@ -2643,10 +2833,10 @@ decorateType (ast * tree)
 
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*       logical &&, ||       */
-/*----------------------------*/
+      /*----------------------------*/
     case AND_OP:
     case OR_OP:
       /* each must me arithmetic type or be a pointer */
@@ -2683,10 +2873,10 @@ decorateType (ast * tree)
       TTYPE (tree) = TETYPE (tree) = newCharLink ();
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*     comparison operators   */
-/*----------------------------*/
+      /*----------------------------*/
     case '>':
     case '<':
     case LE_OP:
@@ -2703,10 +2893,17 @@ decorateType (ast * tree)
       /* if they are pointers they must be castable */
       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
        {
+         if (tree->opval.op==EQ_OP && 
+             !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
+           // we cannot cast a gptr to a !gptr: switch the leaves
+           struct ast *s=tree->left;
+           tree->left=tree->right;
+           tree->right=s;
+         }
          if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
            {
              werror (E_COMPARE_OP);
-             fprintf (stderr, "comparing type ");
+             fprintf (stderr, "comparring type ");
              printTypeChain (LTYPE (tree), stderr);
              fprintf (stderr, "to type ");
              printTypeChain (RTYPE (tree), stderr);
@@ -2731,7 +2928,18 @@ decorateType (ast * tree)
                goto errorTreeReturn;
              }
        }
+      /* 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 == '<') {
+             return tree->right;
+         }
+         if (tree->opval.op == '>') {
+             return tree->left;
+         }
+      }
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) &&
@@ -2750,14 +2958,14 @@ decorateType (ast * tree)
       TTYPE (tree) = TETYPE (tree) = newCharLink ();
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*             sizeof         */
-/*----------------------------*/
+      /*----------------------------*/
     case SIZEOF:               /* evaluate wihout code generation */
       /* change the type to a integer */
       tree->type = EX_VALUE;
-      sprintf (buffer, "%d", (getSize (tree->right->ftype)));
+      SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
       tree->opval.val = constVal (buffer);
       tree->right = tree->left = NULL;
       TETYPE (tree) = getSpec (TTYPE (tree) =
@@ -2830,7 +3038,7 @@ decorateType (ast * tree)
                    break;
                }
            }
-           sprintf (buffer, "%d", typeofv);
+           SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
            tree->opval.val = constVal (buffer);
            tree->right = tree->left = NULL;
            TETYPE (tree) = getSpec (TTYPE (tree) =
@@ -2872,10 +3080,11 @@ decorateType (ast * tree)
       return tree;
 
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+#if 0 // assignment operators are converted by the parser
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*    assignment operators    */
-/*----------------------------*/
+      /*----------------------------*/
     case MUL_ASSIGN:
     case DIV_ASSIGN:
       /* for these it must be both must be integral */
@@ -2888,12 +3097,12 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
 
-      if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, ");
+      if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
+       werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
 
       if (LRVAL (tree))
        {
-         werror (E_LVALUE_REQUIRED, "*= or /=");
+         werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
          goto errorTreeReturn;
        }
       LLVAL (tree) = 1;
@@ -2916,7 +3125,7 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, " ");
+       werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
 
       if (LRVAL (tree))
        {
@@ -2927,10 +3136,10 @@ decorateType (ast * tree)
 
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*    -= operator             */
-/*----------------------------*/
+      /*----------------------------*/
     case SUB_ASSIGN:
       if (!(IS_PTR (LTYPE (tree)) ||
            IS_ARITHMETIC (LTYPE (tree))))
@@ -2951,7 +3160,7 @@ decorateType (ast * tree)
                                            RTYPE (tree)));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, " ");
+       werror (E_CODE_WRITE, "-=");
 
       if (LRVAL (tree))
        {
@@ -2962,10 +3171,10 @@ decorateType (ast * tree)
 
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*          += operator       */
-/*----------------------------*/
+      /*----------------------------*/
     case ADD_ASSIGN:
       /* this is not a unary operation */
       /* if both pointers then problem */
@@ -2992,7 +3201,7 @@ decorateType (ast * tree)
                                            RTYPE (tree)));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, " ");
+       werror (E_CODE_WRITE, "+=");
 
       if (LRVAL (tree))
        {
@@ -3004,11 +3213,12 @@ decorateType (ast * tree)
       tree->opval.op = '=';
 
       return tree;
+#endif
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      straight assignemnt   */
-/*----------------------------*/
+      /*----------------------------*/
     case '=':
       /* cannot be an aggregate */
       if (IS_AGGREGATE (LTYPE (tree)))
@@ -3021,13 +3231,8 @@ decorateType (ast * tree)
       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
        {
          werror (E_TYPE_MISMATCH, "assignment", " ");
-         fprintf (stderr, "type --> '");
-         printTypeChain (RTYPE (tree), stderr);
-         fprintf (stderr, "' ");
-         fprintf (stderr, "assigned to type --> '");
-         printTypeChain (LTYPE (tree), stderr);
-         fprintf (stderr, "'\n");
-         goto errorTreeReturn;
+         printFromToType(RTYPE(tree),LTYPE(tree));
+         //goto errorTreeReturn;
        }
 
       /* if the left side of the tree is of type void
@@ -3044,7 +3249,7 @@ decorateType (ast * tree)
       LLVAL (tree) = 1;
       if (!tree->initMode ) {
        if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
-         werror (E_CODE_WRITE, " ");
+         werror (E_CODE_WRITE, "=");
       }
       if (LRVAL (tree))
        {
@@ -3054,18 +3259,18 @@ decorateType (ast * tree)
 
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*      comma operator        */
-/*----------------------------*/
+      /*----------------------------*/
     case ',':
       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*       function call        */
-/*----------------------------*/
+      /*----------------------------*/
     case CALL:
       parmNumber = 1;
 
@@ -3086,10 +3291,10 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*     return statement       */
-/*----------------------------*/
+      /*----------------------------*/
     case RETURN:
       if (!tree->right)
        goto voidcheck;
@@ -3125,17 +3330,17 @@ decorateType (ast * tree)
 
       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
        {
-         werror (E_VOID_FUNC, currFunc->name);
+         werror (W_VOID_FUNC, currFunc->name);
          goto errorTreeReturn;
        }
 
       TTYPE (tree) = TETYPE (tree) = NULL;
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /*     switch statement       */
-/*----------------------------*/
+      /*----------------------------*/
     case SWITCH:
       /* the switch value must be an integer */
       if (!IS_INTEGRAL (LTYPE (tree)))
@@ -3147,10 +3352,10 @@ decorateType (ast * tree)
       TTYPE (tree) = TETYPE (tree) = NULL;
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /* ifx Statement              */
-/*----------------------------*/
+      /*----------------------------*/
     case IFX:
       tree->left = backPatchLabels (tree->left,
                                    tree->trueLabel,
@@ -3158,10 +3363,10 @@ decorateType (ast * tree)
       TTYPE (tree) = TETYPE (tree) = NULL;
       return tree;
 
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
       /* for Statement              */
-/*----------------------------*/
+      /*----------------------------*/
     case FOR:
 
       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
@@ -3213,7 +3418,7 @@ sizeofOp (sym_link * type)
   checkTypeSanity(type, "(sizeof)");
 
   /* get the size and convert it to character  */
-  sprintf (buff, "%d", getSize (type));
+  SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
 
   /* now convert into value  */
   return constVal (buff);
@@ -3247,7 +3452,7 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
       static int localLbl = 0;
       symbol *localLabel;
 
-      sprintf (buffer, "_and_%d", localLbl++);
+      SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
       localLabel = newSymbol (buffer, NestLevel);
 
       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
@@ -3273,7 +3478,7 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
       static int localLbl = 0;
       symbol *localLabel;
 
-      sprintf (buffer, "_or_%d", localLbl++);
+      SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
       localLabel = newSymbol (buffer, NestLevel);
 
       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
@@ -3335,12 +3540,12 @@ createBlock (symbol * decl, ast * body)
   ast *ex;
 
   /* if the block has nothing */
-  if (!body)
+  if (!body && !decl)
     return NULL;
 
   ex = newNode (BLOCK, NULL, body);
   ex->values.sym = decl;
-
+  
   ex->right = ex->right;
   ex->level++;
   ex->lineno = 0;
@@ -3365,7 +3570,7 @@ createLabel (symbol * label, ast * stmnt)
     label = newSymbol (label->name, label->level);
 
   /* change the name before putting it in add _ */
-  sprintf (name, "%s", label->name);
+  SNPRINTF(name, sizeof(name), "%s", label->name);
 
   /* put the label in the LabelSymbol table    */
   /* but first check if a label of the same    */
@@ -3453,7 +3658,8 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
     }
 
   /* create the case label   */
-  sprintf (caseLbl, "_case_%d_%d",
+  SNPRINTF(caseLbl, sizeof(caseLbl), 
+          "_case_%d_%d",
           swStat->values.switchVals.swNum,
           (int) floatFromVal (caseVal->opval.val));
 
@@ -3482,7 +3688,8 @@ createDefault (ast * swStat, ast * stmnt)
   swStat->values.switchVals.swDefault = 1;
 
   /* create the label  */
-  sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
+  SNPRINTF (defLbl, sizeof(defLbl),
+           "_default_%d", swStat->values.switchVals.swNum);
   return createLabel (newSymbol (defLbl, 0), stmnt);
 }
 
@@ -3505,18 +3712,18 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody)
   }
 
   /* create the labels */
-  sprintf (buffer, "_iffalse_%d", Lblnum);
+  SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
   ifFalse = newSymbol (buffer, NestLevel);
   /* if no else body then end == false */
   if (!elseBody)
     ifEnd = ifFalse;
   else
     {
-      sprintf (buffer, "_ifend_%d", Lblnum);
+      SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
       ifEnd = newSymbol (buffer, NestLevel);
     }
 
-  sprintf (buffer, "_iftrue_%d", Lblnum);
+  SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
   ifTrue = newSymbol (buffer, NestLevel);
 
   Lblnum++;
@@ -3893,7 +4100,7 @@ tryNext2:
 /*-----------------------------------------------------------------*/
 /* optimizeCompare - otimizes compares for bit variables     */
 /*-----------------------------------------------------------------*/
-ast *
+static ast *
 optimizeCompare (ast * root)
 {
   ast *optExpr = NULL;
@@ -3940,63 +4147,6 @@ optimizeCompare (ast * root)
   vright = (root->right->type == EX_VALUE ?
            root->right->opval.val : NULL);
 
-  //#define EXPERIMENTAL
-#ifdef EXPERIMENTAL
-  /* if left is unsigned and right is literal */
-  if (vleft && vright && 
-      IS_UNSIGNED(vleft->etype) &&
-      IS_LITERAL(vright->etype)) {
-    double dval=floatFromVal(vright);
-    int op=root->opval.op;
-
-    fprintf (stderr,"op: '");
-    switch (op) {
-    case LE_OP: fprintf (stderr, "<= '"); break;
-    case EQ_OP: fprintf (stderr, "== '"); break;
-    case GE_OP: fprintf (stderr, ">= '"); break;
-    default: fprintf (stderr, "%c '", op); break;
-    }
-    fprintf (stderr, "%f\n", dval);
-
-    switch (op)
-      {
-      case EQ_OP:
-      case LE_OP:
-      case '<':
-       if (dval<0 || (op=='<' && dval==0)) {
-         // unsigned is never < 0
-         werror (W_IF_NEVER_TRUE);
-         optExpr = newAst_VALUE (constVal("0"));
-         return decorateType (optExpr);
-       }
-       if (dval==0) {
-         if (op==LE_OP) {
-           // change this into a cheaper EQ_OP
-           fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
-           root->opval.op=EQ_OP;
-           return root;
-         }
-       }
-       break;
-      case GE_OP:
-      case '>':
-       if (dval>0 || (op==GE_OP && dval==0)) {
-         // unsigned is never < 0
-         werror (W_IF_ALWAYS_TRUE);
-         optExpr = newAst_VALUE (constVal("1"));
-         return decorateType (optExpr);
-       }
-       if (dval==0) {
-         if (op=='>') {
-           // change this into a cheaper reversed EQ_OP
-           fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
-           root->opval.op=EQ_OP;
-         }
-       }
-      }
-  }
-#endif
-
   /* if left is a BITVAR in BITSPACE */
   /* and right is a LITERAL then opt- */
   /* imize else do nothing       */
@@ -4205,7 +4355,7 @@ createFunction (symbol * name, ast * body)
     name->stack = SPEC_STAK (fetype) = stack;
 
   /* name needs to be mangled */
-  sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
+  SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
 
   body = resolveSymbols (body);        /* resolve the symbols */
   body = decorateType (body);  /* propagateType & do semantic checks */
@@ -4247,6 +4397,7 @@ skipall:
 
   /* dealloc the block variables */
   processBlockVars (body, &stack, DEALLOCATE);
+  outputDebugStackSymbols();
   /* deallocate paramaters */
   deallocParms (FUNC_ARGS(name->type));
 
@@ -4261,8 +4412,8 @@ skipall:
   addSet (&operKeyReset, name);
   applyToSet (operKeyReset, resetParmKey);
 
-  if (options.debug)
-    cdbStructBlock (1, cdbFile);
+  if (options.debug)    
+    cdbStructBlock(1);
 
   cleanUpLevel (LabelTab, 0);
   cleanUpBlock (StructTab, 1);
@@ -4274,7 +4425,7 @@ skipall:
 }
 
 
-#define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
+#define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
 /*-----------------------------------------------------------------*/
 /* ast_print : prints the ast (for debugging purposes)             */
 /*-----------------------------------------------------------------*/
@@ -4308,7 +4459,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                value *args=FUNC_ARGS(tree->left->opval.val->type);
                fprintf(outfile,"FUNCTION (%s=%p) type (", 
                        tree->left->opval.val->name, tree);
-               printTypeChain (tree->ftype,outfile);
+               printTypeChain (tree->left->opval.val->type->next,outfile);
                fprintf(outfile,") args (");
                do {
                  if (arg) {
@@ -4342,9 +4493,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                return;
        }
        if (tree->opval.op == NULLOP) {
-               fprintf(outfile,"\n");
                ast_print(tree->left,outfile,indent);
-               fprintf(outfile,"\n");
                ast_print(tree->right,outfile,indent);
                return ;
        }
@@ -4766,14 +4915,14 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                ast_print(tree->right,outfile,indent+2);
                return;
        case OR_ASSIGN:
-               fprintf(outfile,"ORASS(*=) (%p) type (",tree);
+               fprintf(outfile,"ORASS(|=) (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
                ast_print(tree->left,outfile,indent+2);
                ast_print(tree->right,outfile,indent+2);
                return;
        case XOR_ASSIGN:
-               fprintf(outfile,"XORASS(*=) (%p) type (",tree);
+               fprintf(outfile,"XORASS(^=) (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
                ast_print(tree->left,outfile,indent+2);
@@ -4787,7 +4936,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                ast_print(tree->right,outfile,indent+2);
                return;
        case LEFT_ASSIGN:
-               fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
+               fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
                ast_print(tree->left,outfile,indent+2);
@@ -4862,7 +5011,9 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                /*----------------------------*/
        case RETURN:
                fprintf(outfile,"RETURN (%p) type (",tree);
-               printTypeChain(tree->right->ftype,outfile);
+               if (tree->right) {
+                   printTypeChain(tree->right->ftype,outfile);
+               }
                fprintf(outfile,")\n");
                ast_print(tree->right,outfile,indent+2);
                return ;
@@ -4902,15 +5053,23 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                fprintf(outfile,"IF (%p) \n",tree);
                ast_print(tree->left,outfile,indent+2);
                if (tree->trueLabel) {
-                       INDENT(indent,outfile);
+                       INDENT(indent+2,outfile);
                        fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
                }
                if (tree->falseLabel) {
-                       INDENT(indent,outfile);
+                       INDENT(indent+2,outfile);
                        fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
                }
                ast_print(tree->right,outfile,indent+2);
                return ;
+               /*----------------------------*/
+               /* goto Statement              */
+               /*----------------------------*/
+       case GOTO:
+               fprintf(outfile,"GOTO (%p) \n",tree);
+               ast_print(tree->left,outfile,indent+2);
+               fprintf(outfile,"\n");
+               return ;
                /*------------------------------------------------------------------*/
                /*----------------------------*/
                /* for Statement              */