* src/SDCCast.c (processParms): fixed bug #920866; decorateType() can return an optim...
[fw/sdcc] / src / SDCCast.c
index 29ac0a73fca8523130e9c9b51b3c399a900da27e..b56020d2119ddc9c11625601b01e9726647a055e 100644 (file)
@@ -22,6 +22,8 @@
    what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+#define DEBUG_CF(x) /* puts(x); */
+
 #include "common.h"
 
 int currLineno = 0;
@@ -647,7 +649,7 @@ reverseParms (ast * ptree)
 static int
 processParms (ast *func,
              value *defParm,
-             ast *actParm,
+             ast **actParm,
              int *parmNumber, /* unused, although updated */
              bool rightmost)
 {
@@ -655,7 +657,7 @@ processParms (ast *func,
   sym_link *functype;
   
   /* if none of them exist */
-  if (!defParm && !actParm)
+  if (!defParm && !*actParm)
     return 0;
 
   if (defParm)
@@ -679,32 +681,33 @@ processParms (ast *func,
   if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
     {
       werror (W_NONRENT_ARGS);
+      fatalError++;
       return 1;
     }
 
   /* if defined parameters ended but actual parameters */
   /* exist and this is not defined as a variable arg   */
-  if (!defParm && actParm && !IFFUNC_HASVARARGS(functype))
+  if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
     {
       werror (E_TOO_MANY_PARMS);
       return 1;
     }
 
   /* if defined parameters present but no actual parameters */
-  if (defParm && !actParm)
+  if (defParm && !*actParm)
     {
       werror (E_TOO_FEW_PARMS);
       return 1;
     }
 
   /* if this is a PARAM node then match left & right */
-  if (actParm->type == EX_OP && actParm->opval.op == PARAM)
+  if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
     {
-      actParm->decorated = 1;
+      (*actParm)->decorated = 1;
       return (processParms (func, defParm,
-                           actParm->left,  parmNumber, FALSE) ||
+                           &(*actParm)->left,  parmNumber, FALSE) ||
              processParms (func, defParm ? defParm->next : NULL,
-                           actParm->right, parmNumber, rightmost));
+                           &(*actParm)->right, parmNumber, rightmost));
     }
   else if (defParm) /* not vararg */
     {
@@ -724,28 +727,28 @@ processParms (ast *func,
   /* decorate parameter */
   resultType = defParm ? getResultTypeFromType (defParm->etype) :
                          RESULT_TYPE_NONE;
-  actParm = decorateType (actParm, resultType);
+  *actParm = decorateType (*actParm, resultType);
 
-  if (IS_VOID(actParm->ftype))
+  if (IS_VOID((*actParm)->ftype))
     {
       werror (E_VOID_VALUE_USED);
       return 1;
     }
 
   /* If this is a varargs function... */
-  if (!defParm && actParm && IFFUNC_HASVARARGS(functype))
+  if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
     {
       ast *newType = NULL;
       sym_link *ftype;
 
-      if (IS_CAST_OP (actParm)
-         || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
+      if (IS_CAST_OP (*actParm)
+         || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
        {
          /* Parameter was explicitly typecast; don't touch it. */
          return 0;
        }
 
-      ftype = actParm->ftype;
+      ftype = (*actParm)->ftype;
 
       /* If it's a char, upcast to int. */
       if (IS_INTEGRAL (ftype)
@@ -769,55 +772,55 @@ processParms (ast *func,
       if (newType)
        {
          /* cast required; change this op to a cast. */
-         ast *parmCopy = resolveSymbols (copyAst (actParm));
+         ast *parmCopy = resolveSymbols (copyAst (*actParm));
 
-         actParm->type = EX_OP;
-         actParm->opval.op = CAST;
-         actParm->left = newType;
-         actParm->right = parmCopy;
-         actParm->decorated = 0; /* force typechecking */
-         decorateType (actParm, RESULT_TYPE_NONE);
+         (*actParm)->type = EX_OP;
+         (*actParm)->opval.op = CAST;
+         (*actParm)->left = newType;
+         (*actParm)->right = parmCopy;
+         (*actParm)->decorated = 0; /* force typechecking */
+         decorateType (*actParm, RESULT_TYPE_NONE);
        }
       return 0;
     } /* vararg */
 
   /* if defined parameters ended but actual has not & */
   /* reentrant */
-  if (!defParm && actParm &&
+  if (!defParm && *actParm &&
       (options.stackAuto || IFFUNC_ISREENT (functype)))
     return 0;
 
-  resolveSymbols (actParm);
+  resolveSymbols (*actParm);
   
   /* the parameter type must be at least castable */
-  if (compareType (defParm->type, actParm->ftype) == 0)
+  if (compareType (defParm->type, (*actParm)->ftype) == 0)
     {
       werror (E_INCOMPAT_TYPES);
-      printFromToType (actParm->ftype, defParm->type);
+      printFromToType ((*actParm)->ftype, defParm->type);
       return 1;
     }
 
   /* if the parameter is castable then add the cast */
-  if (compareType (defParm->type, actParm->ftype) < 0)
+  if (compareType (defParm->type, (*actParm)->ftype) < 0)
     {
       ast *pTree;
 
       resultType = getResultTypeFromType (defParm->etype);
-      pTree = resolveSymbols (copyAst (actParm));
+      pTree = resolveSymbols (copyAst (*actParm));
       
       /* now change the current one to a cast */
-      actParm->type = EX_OP;
-      actParm->opval.op = CAST;
-      actParm->left = newAst_LINK (defParm->type);
-      actParm->right = pTree;
-      actParm->decorated = 0; /* force typechecking */
-      decorateType (actParm, resultType);
+      (*actParm)->type = EX_OP;
+      (*actParm)->opval.op = CAST;
+      (*actParm)->left = newAst_LINK (defParm->type);
+      (*actParm)->right = pTree;
+      (*actParm)->decorated = 0; /* force typechecking */
+      decorateType (*actParm, resultType);
     }
 
   /* 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);
+  (*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;
 }
@@ -870,7 +873,7 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist)
     }
 
   if (iloop) {
-    werrorfl (filename, sym->opval.val->sym->lineDef,
+    werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
              W_EXCESS_INITIALIZERS, "struct", 
              sym->opval.val->sym->name);
   }
@@ -931,6 +934,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
            // Array size was specified, and we have more initializers than needed.
            char *name=sym->opval.val->sym->name;
            int lineno=sym->opval.val->sym->lineDef;
+           char *filename=sym->opval.val->sym->fileDef;
            
            werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
        }
@@ -957,6 +961,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;
+               char *filename=sym->opval.val->sym->fileDef;
                werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
                
                break;
@@ -1131,7 +1136,7 @@ gatherAutoInit (symbol * autoChain)
            work = initAggregates (sym, sym->ival, NULL);
          } else {
            if (getNelements(sym->type, sym->ival)>1) {
-             werrorfl (filename, sym->lineDef,
+             werrorfl (sym->fileDef, sym->lineDef,
                        W_EXCESS_INITIALIZERS, "scalar", 
                        sym->name);
            }
@@ -1167,7 +1172,7 @@ gatherAutoInit (symbol * autoChain)
            work = initAggregates (sym, sym->ival, NULL);
          } else {
            if (getNelements(sym->type, sym->ival)>1) {
-             werrorfl (filename, sym->lineDef,
+             werrorfl (sym->fileDef, sym->lineDef,
                        W_EXCESS_INITIALIZERS, "scalar", 
                        sym->name);
            }
@@ -1976,7 +1981,7 @@ searchLitOp (ast *tree, ast **parent, const char *ops)
           tree->right->right &&
           (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
        {
-         if (IS_LITERAL (RTYPE (tree->right)) ^
+         if (IS_LITERAL (RTYPE (tree->right)) !=
              IS_LITERAL (LTYPE (tree->right)))
            {
              tree->right->decorated = 0;
@@ -1993,7 +1998,7 @@ searchLitOp (ast *tree, ast **parent, const char *ops)
           tree->left->right &&
          (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
        {
-         if (IS_LITERAL (RTYPE (tree->left)) ^
+         if (IS_LITERAL (RTYPE (tree->left)) !=
              IS_LITERAL (LTYPE (tree->left)))
            {
              tree->left->decorated = 0;
@@ -2016,10 +2021,18 @@ RESULT_TYPE
 getResultTypeFromType (sym_link *type)
 {
   /* type = getSpec (type); */
-  if (IS_BITVAR (type))
+  if (IS_BIT (type))
     return RESULT_TYPE_BIT;
   if (IS_BITFIELD (type))
-    return RESULT_TYPE_CHAR;
+    {
+      int blen = SPEC_BLEN (type);
+      
+      if (blen <= 1)
+        return RESULT_TYPE_BIT;
+      if (blen <= 8)
+        return RESULT_TYPE_CHAR;
+      return RESULT_TYPE_INT;
+    }
   if (IS_CHAR (type))
     return RESULT_TYPE_CHAR;
   if (   IS_INT (type)
@@ -2048,7 +2061,7 @@ addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
        upCasted = TRUE;
        break;
       case RESULT_TYPE_CHAR:
-       if (getSize (tree->etype) <= 1)
+       if (IS_CHAR (tree->etype))
          return tree;
        newLink = newCharLink();
        break;
@@ -2081,6 +2094,7 @@ addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
     }
   tree->decorated = 0;
   tree = newNode (CAST, newAst_LINK (newLink), tree);
+  tree->lineno = tree->right->lineno;
   /* keep unsigned type during cast to smaller type,
      but not when promoting from char to int */
   if (!upCasted)
@@ -2101,6 +2115,10 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType)
       case ':':
       case '|':
       case '^':
+      case '*':
+      case '+':
+      case '-':
+      case LABEL:
        return resultType;
       case '&':
        if (!tree->right)
@@ -2108,6 +2126,8 @@ resultTypePropagate (ast *tree, RESULT_TYPE resultType)
          return RESULT_TYPE_NONE;
        else
          return resultType;
+      case IFX:
+       return RESULT_TYPE_IFX;
       default:
        return RESULT_TYPE_NONE;
     }
@@ -2277,7 +2297,10 @@ decorateType (ast * tree, RESULT_TYPE resultType)
        upon tree->opval.op, if resultType can be propagated */
     resultTypeProp = resultTypePropagate (tree, resultType);
 
-    dtl = decorateType (tree->left, resultTypeProp);
+    if (tree->opval.op == '?')
+      dtl = decorateType (tree->left, RESULT_TYPE_IFX);
+    else
+      dtl = decorateType (tree->left, resultTypeProp);
 
     /* if an array node, we may need to swap branches */
     if (tree->opval.op == '[')
@@ -2541,9 +2564,10 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              return decorateType (otree, RESULT_CHECK);
          }
 
-         tree->left  = addCast (tree->left,  resultType, FALSE);
-         tree->right = addCast (tree->right, resultType, FALSE);
-         TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
+         TTYPE (tree) = computeType (LTYPE (tree),
+                                     RTYPE (tree),
+                                     resultType,
+                                     tree->opval.op);
          TETYPE (tree) = getSpec (TTYPE (tree));
 
           /* if left is a literal exchange left & right */
@@ -2563,11 +2587,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              ast *litTree = searchLitOp (tree, &parent, "&");
              if (litTree)
                {
-                 ast *tTree = litTree->left;
+                 DEBUG_CF("&")
+                 ast *tTree = litTree->left;
                  litTree->left = tree->right;
                  tree->right = tTree;
                  /* both operands in tTree are literal now */
-                 decorateType (parent, RESULT_CHECK);
+                 decorateType (parent, resultType);
                }
            }
 
@@ -2690,11 +2715,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          ast *litTree = searchLitOp (tree, &parent, "|");
          if (litTree)
            {
+             DEBUG_CF("|")
              ast *tTree = litTree->left;
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in tTree are literal now */
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
         }
       /* fall through */
@@ -2747,21 +2773,21 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          ast *litTree = searchLitOp (tree, &parent, "^");
          if (litTree)
            {
+             DEBUG_CF("^")
              ast *tTree = litTree->left;
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in litTree are literal now */
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
         }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      tree->left  = addCast (tree->left,  resultType, FALSE);
-      tree->right = addCast (tree->right, resultType, FALSE);
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           FALSE));
+                                           resultType,
+                                           tree->opval.op));
 
       return tree;
 
@@ -2789,10 +2815,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
        }
 
       LRVAL (tree) = RRVAL (tree) = 1;
+
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-               ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
+                                           resultType,
+                                           tree->opval.op));
 
       /* if right is a literal and */
       /* left is also a division by a literal then */
@@ -2808,11 +2836,14 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              if (IS_LITERAL (RTYPE (litTree)))
                {
                  /* foo_div */
-                 litTree->right = newNode ('*', litTree->right, tree->right);
+                 DEBUG_CF("div r")
+                 litTree->right = newNode ('*',
+                                           litTree->right,
+                                           copyAst (tree->right));
                  litTree->right->lineno = tree->lineno;
 
                  tree->right->opval.val = constVal ("1");
-                 decorateType (parent, RESULT_CHECK);
+                 decorateType (parent, resultType);
                }
              else
                {
@@ -2820,7 +2851,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                     We can't call decorateType(parent, RESULT_CHECK), because
                     this would cause an infinit loop. */
                  parent->decorated = 1;
-                 decorateType (litTree, RESULT_CHECK);
+                 decorateType (litTree, resultType);
                }
            }
        }
@@ -2858,7 +2889,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-               ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
+                                           resultType,
+                                           tree->opval.op));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2959,11 +2991,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          ast *litTree = searchLitOp (tree, &parent, "*");
          if (litTree)
            {
+             DEBUG_CF("mul")
              ast *tTree = litTree->left;
              litTree->left = tree->right;
              tree->right = tTree;
              /* both operands in litTree are literal now */
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
         }
 
@@ -2973,8 +3006,9 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                                   computeType (LTYPE (tree),
                                                RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
-      
+                                               resultType,
+                                               tree->opval.op));
+
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -3037,6 +3071,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
        {
          tree->type = EX_VALUE;
+         tree->left  = addCast (tree->left,  resultType, TRUE);
+          tree->right = addCast (tree->right, resultType, TRUE);
          tree->opval.val = valPlus (valFromType (LETYPE (tree)),
                                     valFromType (RETYPE (tree)));
          tree->right = tree->left = NULL;
@@ -3068,6 +3104,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              if (litTree->opval.op == '+')
                {
                  /* foo_aa */
+                 DEBUG_CF("+ 1 AA")
                  ast *tTree = litTree->left;
                  litTree->left = tree->right;
                  tree->right = tree->left;
@@ -3077,6 +3114,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                {
                  if (IS_LITERAL (RTYPE (litTree)))
                    {
+                     DEBUG_CF("+ 2 ASR")
                      /* foo_asr */
                      ast *tTree = litTree->left;
                      litTree->left = tree->right;
@@ -3084,6 +3122,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                    }
                  else
                    {
+                     DEBUG_CF("+ 3 ASL")
                      /* foo_asl */
                      ast *tTree = litTree->right;
                      litTree->right = tree->right;
@@ -3092,7 +3131,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                      tree->opval.op = '-';
                    }
                }
-             decorateType (parent, RESULT_CHECK);
+             decorateType (parent, resultType);
            }
        }
 
@@ -3107,8 +3146,9 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           tree->right = addCast (tree->right, resultType, TRUE);
           TETYPE (tree) = getSpec (TTYPE (tree) =
                                     computeType (LTYPE (tree),
-                                                 RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                                 RTYPE (tree),
+                                                 resultType,
+                                                 tree->opval.op));
        }
        
       return tree;
@@ -3177,6 +3217,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
        {
          tree->type = EX_VALUE;
+         tree->left  = addCast (tree->left,  resultType, TRUE);
+         tree->right = addCast (tree->right, resultType, TRUE);
          tree->opval.val = valMinus (valFromType (LETYPE (tree)),
                                      valFromType (RETYPE (tree)));
          tree->right = tree->left = NULL;
@@ -3210,10 +3252,12 @@ decorateType (ast * tree, RESULT_TYPE resultType)
        {
          tree->left  = addCast (tree->left,  resultType, TRUE);
          tree->right = addCast (tree->right, resultType, TRUE);
+
          TETYPE (tree) = getSpec (TTYPE (tree) =
                                     computeType (LTYPE (tree),
-                                                 RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                                 RTYPE (tree),
+                                                 resultType,
+                                                 tree->opval.op));
        }
 
       LRVAL (tree) = RRVAL (tree) = 1;
@@ -3232,30 +3276,39 @@ decorateType (ast * tree, RESULT_TYPE resultType)
              if (litTree->opval.op == '+')
                {
                  /* foo_sa */
-                 litTree->right = newNode ('-', litTree->right, tree->right);
-                 litTree->right->lineno = tree->lineno;
-
-                 tree->right->opval.val = constVal ("0");
+                 DEBUG_CF("- 1 SA")
+                 ast *tTree = litTree->left;
+                 litTree->left = litTree->right;
+                 litTree->right = tree->right;
+                 tree->right = tTree;
+                 tree->opval.op = '+';
+                 litTree->opval.op = '-';
                }
              else if (litTree->opval.op == '-')
                {
                  if (IS_LITERAL (RTYPE (litTree)))
                    {
                      /* foo_ssr */
-                     litTree->right = newNode ('+', tree->right, litTree->right);
-                     litTree->right->lineno = tree->lineno;
-
-                     tree->right->opval.val = constVal ("0");
+                     DEBUG_CF("- 2 SSR")
+                     ast *tTree = litTree->left;
+                     litTree->left = tree->right;
+                     tree->right = litParent->left;
+                     litParent->left = tTree;
+                     litTree->opval.op = '+';
+                     
+                     tree->decorated = 0;
+                     decorateType (tree, resultType);
                    }
                  else
                    {
                      /* foo_ssl */
+                     DEBUG_CF("- 3 SSL")
                      ast *tTree = litTree->right;
                      litTree->right = tree->right;
                      tree->right = tTree;
                    }
                }
-             decorateType (litParent, RESULT_CHECK);
+             decorateType (litParent, resultType);
            }
        }
       return tree;
@@ -3340,6 +3393,10 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          goto errorTreeReturn;
        }
 
+      /* make smaller type only if it's a LEFT_OP */
+      if (tree->opval.op == LEFT_OP)
+        tree->left = addCast (tree->left, resultType, TRUE);
+      
       /* if they are both literal then */
       /* rewrite the tree */
       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
@@ -3357,11 +3414,11 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       LRVAL (tree) = RRVAL (tree) = 1;
       if (tree->opval.op == LEFT_OP)
        {
-         tree->left = addCast (tree->left, resultType, TRUE);
          TETYPE (tree) = getSpec (TTYPE (tree) =
                                       computeType (LTYPE (tree),
-                                                   RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                                   NULL,
+                                                   resultType,
+                                                   tree->opval.op));
        }
       else /* RIGHT_OP */
        {
@@ -3580,7 +3637,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       /*----------------------------*/
     case AND_OP:
     case OR_OP:
-      /* each must me arithmetic type or be a pointer */
+      /* each must be arithmetic type or be a pointer */
       if (!IS_PTR (LTYPE (tree)) &&
          !IS_ARRAY (LTYPE (tree)) &&
          !IS_INTEGRAL (LTYPE (tree)))
@@ -3682,8 +3739,14 @@ decorateType (ast * tree, RESULT_TYPE resultType)
            }
          if (tree->opval.op == '>')
            {
-             /* if the parent is an ifx, then we could do */
-             /* return tree->left; */
+             if (resultType == RESULT_TYPE_IFX)
+               {
+                 /* the parent is an ifx: */
+                 /* if (unsigned value) */
+                 return tree->left;
+               }
+             
+             /* (unsigned value) ? 1 : 0 */
              tree->opval.op = '?';
              tree->right = newNode (':',
                                     newAst_VALUE (constVal ("1")),
@@ -3717,8 +3780,13 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       /*----------------------------*/
     case SIZEOF:               /* evaluate wihout code generation */
       /* change the type to a integer */
+      {
+       int size = getSize (tree->right->ftype);
+       SNPRINTF(buffer, sizeof(buffer), "%d", size);
+       if (!size && !IS_VOID(tree->right->ftype))
+         werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
+      }
       tree->type = EX_VALUE;
-      SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
       tree->opval.val = constVal (buffer);
       tree->right = tree->left = NULL;
       TETYPE (tree) = getSpec (TTYPE (tree) =
@@ -3833,7 +3901,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          goto errorTreeReturn;
        }
 
-      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
+      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
+                                  resultType, tree->opval.op);
       TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
@@ -3916,7 +3985,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           FALSE));
+                                           RESULT_TYPE_NOPROM,
+                                           tree->opval.op));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "-=");
@@ -3958,7 +4028,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           FALSE));
+                                           RESULT_TYPE_NOPROM,
+                                           tree->opval.op));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "+=");
@@ -4057,7 +4128,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          functype = LTYPE (tree);
 
        if (processParms (tree->left, FUNC_ARGS(functype),
-                         tree->right, &parmNumber, TRUE)) {
+                         &tree->right, &parmNumber, TRUE)) {
          goto errorTreeReturn;
         }
 
@@ -4200,12 +4271,15 @@ value *
 sizeofOp (sym_link * type)
 {
   char buff[10];
+  int size;
 
   /* make sure the type is complete and sane */
   checkTypeSanity(type, "(sizeof)");
 
   /* get the size and convert it to character  */
-  SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
+  SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
+  if (!size && !IS_VOID(type))
+    werror (E_SIZEOF_INCOMPLETE_TYPE);
 
   /* now convert into value  */
   return constVal (buff);