* src/SDCCsymt.c (processFuncArgs): fixed bug #896796
[fw/sdcc] / src / SDCCsymt.c
index eafcb45d86d75b468225e3683a16e53cc991f4a3..e462c2b4766906a53968d9be6dddd26d66998b9b 100644 (file)
@@ -293,6 +293,7 @@ newSymbol (char *name, int scope)
   sym->level = scope;          /* set the level    */
   sym->block = currBlockno;
   sym->lineDef = mylineno;     /* set the line number */
+  sym->fileDef = currFname;
   return sym;
 }
 
@@ -1518,7 +1519,9 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
   sym_link *rType;
   sym_link *reType;
   sym_link *etype1 = getSpec (type1);
-  sym_link *etype2 = getSpec (type2);
+  sym_link *etype2;
+   
+  etype2 = type2 ? getSpec (type2) : type1;
 
   /* if one of them is a float then result is a float */
   /* here we assume that the types passed are okay */
@@ -1553,11 +1556,25 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
   if (IS_CHAR (reType) && promoteCharToInt)
     SPEC_NOUN (reType) = V_INT;
 
-  if (   (   (   SPEC_USIGN (etype1)
-             && (getSize (etype1) >= getSize (reType)))
+  if (!IS_FLOAT (reType)
+      && (   (   SPEC_USIGN (etype1)
+              /* if this operand is promoted to a larger
+                type don't check it's signedness */
+             && (getSize (etype1) >= getSize (reType))
+             /* char has to handled as it would have
+                been promoted to int */
+             && !IS_CHAR (etype1))
+             /* same for 2nd operand */  
          || (   SPEC_USIGN (etype2)
-             && (getSize (etype2) >= getSize (reType))))
-      && !IS_FLOAT (reType))
+             && (getSize (etype2) >= getSize (reType))
+             && !IS_CHAR (etype2))
+         /* if both are unsigned char and not promoted
+            let the result be unsigned too */
+         || (   SPEC_USIGN (etype1)
+             && SPEC_USIGN (etype2)
+             && IS_CHAR (etype1)
+             && IS_CHAR (etype2)
+             && !promoteCharToInt)))
     SPEC_USIGN (reType) = 1;
   else
     SPEC_USIGN (reType) = 0;
@@ -2144,10 +2161,9 @@ processFuncArgs (symbol * func)
   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
 
-  // if this is a pointer to a function
-  if (IS_PTR(funcType)) {
+  /* find the function declaration within the type */
+  while (funcType && !IS_FUNC(funcType))
     funcType=funcType->next;
-  }
 
   /* if this function has variable argument list */
   /* then make the function a reentrant one    */
@@ -2227,10 +2243,13 @@ processFuncArgs (symbol * func)
          val->sym->etype = getSpec (val->sym->type);
          val->sym->_isparm = 1;
          strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
+         #if 0
+         /* ?? static functions shouldn't imply static parameters - EEP */
          if (IS_SPEC(func->etype)) {
            SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
              SPEC_STAT (func->etype);
          }
+         #endif
          addSymChain (val->sym);
 
        }
@@ -2242,10 +2261,14 @@ processFuncArgs (symbol * func)
          val->sym->_isparm = 1;
          SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
            (options.model != MODEL_SMALL ? xdata : data);
+         
+         #if 0
+         /* ?? static functions shouldn't imply static parameters - EEP */
          if (IS_SPEC(func->etype)) {
            SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
              SPEC_STAT (func->etype);
          }
+         #endif
        }
       if (!isinSet(operKeyReset, val->sym)) {
        addSet (&operKeyReset, val->sym);