* src/SDCCglue.c, src/SDCCast.c:
[fw/sdcc] / src / SDCCast.c
index 702d6ec19582a493dbc4acbc28ed4f9cc874f4f8..2e6d1f8e8cdda4e9a7f602fd2be6c76608d09b03 100644 (file)
@@ -168,7 +168,7 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
 }
 
 /*-----------------------------------------------------------------*/
-/* copyAstValues - copies value portion of ast if needed     */
+/* copyAstValues - copies value portion of ast if needed           */
 /*-----------------------------------------------------------------*/
 void
 copyAstValues (ast * dest, ast * src)
@@ -540,7 +540,6 @@ resolveSymbols (ast * tree)
             werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
                       tree->falseLabel->name);
         }
-
     }
 
   /* if this is a label resolve it from the labelTab */
@@ -548,7 +547,6 @@ resolveSymbols (ast * tree)
       tree->opval.val->sym &&
       tree->opval.val->sym->islbl)
     {
-
       symbol *csym = findSym (LabelTab, tree->opval.val->sym,
                               tree->opval.val->sym->name);
 
@@ -566,7 +564,6 @@ resolveSymbols (ast * tree)
       tree->opval.val->sym &&
       !tree->opval.val->sym->implicit)
     {
-
       symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
 
       /* if found in the symbol table & they are not the same */
@@ -582,7 +579,6 @@ resolveSymbols (ast * tree)
       /* is an integer in data space      */
       if (!csym && !tree->opval.val->sym->implicit)
         {
-
           /* if this is a function name then */
           /* mark it as returning an int     */
           if (tree->funcName)
@@ -854,8 +850,12 @@ processParms (ast *func,
       ast *newType = NULL;
       sym_link *ftype;
 
-      if (IS_CAST_OP (*actParm)
-          || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
+      /* don't perform integer promotion of explicitly typecasted variable arguments
+       * if sdcc extensions are enabled */
+      if (options.std_sdcc &&
+        (IS_CAST_OP (*actParm) ||
+        (IS_AST_SYM_VALUE (*actParm) && AST_VALUES (*actParm, removedCast)) ||
+        (IS_AST_LIT_VALUE (*actParm) && AST_VALUES (*actParm, literalFromCast))))
         {
           /* Parameter was explicitly typecast; don't touch it. */
           return 0;
@@ -957,10 +957,13 @@ createIvalType (ast * sym, sym_link * type, initList * ilist)
   ast *iExpr;
 
   /* if initList is deep */
-  if (ilist->type == INIT_DEEP)
+  if (ilist && ilist->type == INIT_DEEP)
     ilist = ilist->init.deep;
 
-  iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
+  if (ilist)
+    iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
+  else
+    iExpr = newAst_VALUE (valueFromLit (0));
   return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
 }
 
@@ -974,40 +977,46 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
   ast *lAst;
   symbol *sflds;
   initList *iloop;
+  sym_link * etype = getSpec (type);
 
   sflds = SPEC_STRUCT (type)->fields;
-  if (ilist->type != INIT_DEEP)
+  if (ilist && ilist->type != INIT_DEEP)
     {
       werror (E_INIT_STRUCT, "");
       return NULL;
     }
 
-  iloop = ilist->init.deep;
+  iloop = ilist ? ilist->init.deep : NULL;
 
   for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
     {
       /* if we have come to end */
-      if (!iloop)
-        break;
+      if (!iloop && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype)))
+        {
+          break;
+        }
+
       sflds->implicit = 1;
       lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
       lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
       rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
                                                        iloop, rast, rootValue)),
                            RESULT_TYPE_NONE);
-
     }
 
-  if (iloop) {
-    werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
-              W_EXCESS_INITIALIZERS, "struct",
-              sym->opval.val->sym->name);
+  if (iloop)
+    {
+      if (IS_AST_VALUE (sym))
+        werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
+                  W_EXCESS_INITIALIZERS, "struct",
+                  sym->opval.val->sym->name);
+      else
+        werrorfl (sym->filename, sym->lineno, E_INIT_COUNT);
   }
 
   return rast;
 }
 
-
 /*-----------------------------------------------------------------*/
 /* createIvalArray - generates code for array initialization       */
 /*-----------------------------------------------------------------*/
@@ -1018,6 +1027,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
   initList *iloop;
   int lcnt = 0, size = 0;
   literalList *literalL;
+  sym_link * etype = getSpec (type);
 
   /* take care of the special   case  */
   /* array of characters can be init  */
@@ -1025,23 +1035,29 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
   if (IS_CHAR (type->next))
     if ((rast = createIvalCharPtr (sym,
                                    type,
-                        decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
+                                   decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
                                    rootValue)))
 
       return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
 
-  /* not the special case             */
-  if (ilist->type != INIT_DEEP)
-  {
+  /* not the special case */
+  if (ilist && ilist->type != INIT_DEEP)
+    {
       werror (E_INIT_STRUCT, "");
       return NULL;
-  }
+    }
 
-  iloop = ilist->init.deep;
+  iloop = ilist ? ilist->init.deep : NULL;
   lcnt = DCL_ELEM (type);
 
-  if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
-  {
+  if (!iloop &&
+      (!lcnt || !DCL_ELEM (type) || !AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype)))
+    {
+      return NULL;
+    }
+
+  if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL, lcnt))
+    {
       ast *aSym;
 
       aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
@@ -1051,45 +1067,48 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
 
       // Make sure size is set to length of initializer list.
       while (iloop)
-      {
+        {
           size++;
           iloop = iloop->next;
-      }
+        }
 
       if (lcnt && size > lcnt)
-      {
+        {
           // Array size was specified, and we have more initializers than needed.
           werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
-            W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
-      }
-  }
+                    W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
+        }
+    }
   else
-  {
+    {
       for (;;)
-      {
+        {
           ast *aSym;
 
+          if (!iloop &&
+              (!lcnt || !DCL_ELEM (type) || !AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype)))
+            {
+              break;
+            }
+
           aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
           aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
           rast = createIval (aSym, type->next, iloop, rast, rootValue);
+          lcnt--;
           iloop = (iloop ? iloop->next : NULL);
-          if (!iloop)
-          {
-              break;
-          }
 
           /* no of elements given and we    */
           /* have generated for all of them */
-          if (!--lcnt)
-          {
+          if (!lcnt && iloop)
+            {
               // is this a better way? at least it won't crash
               char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
               werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name);
 
               break;
-          }
-      }
-  }
+            }
+        }
+    }
 
   /* if we have not been given a size  */
   if (!DCL_ELEM (type))
@@ -1122,6 +1141,29 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
     return newNode ('=', sym, iexpr);
 
   /* left side is an array so we have to assign each element */
+  if (!iexpr)
+    {
+      /* for each character generate an assignment */
+      /* to the array element */
+      unsigned int i = 0;
+      unsigned int symsize = getSize (type);
+
+      if (!AST_SYMBOL (rootVal)->islocal || SPEC_STAT (getSpec (type)))
+        return NULL;
+
+      for (i = 0; i < symsize; ++i)
+        {
+          rast = newNode (NULLOP,
+                          rast,
+                          newNode ('=',
+                                   newNode ('[', sym,
+                                            newAst_VALUE (valueFromLit ((float) i))),
+                                   newAst_VALUE (valueFromLit (0))));
+        }
+
+      return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
+    }
+
   if ((IS_LITERAL (iexpr->etype) ||
        SPEC_SCLS (iexpr->etype) == S_CODE)
       && IS_ARRAY (iexpr->ftype))
@@ -1133,9 +1175,9 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
       unsigned int symsize = getSize (type);
 
       size = getSize (iexpr->ftype);
-      if (symsize && size>symsize)
+      if (symsize && size > symsize)
         {
-          if (size>(symsize+1))
+          if (size > symsize)
             {
               char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
 
@@ -1145,15 +1187,14 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
           size = symsize;
         }
 
-      for (i=0;i<size;i++)
+      for (i = 0; i < size; i++)
         {
           rast = newNode (NULLOP,
                           rast,
                           newNode ('=',
                                    newNode ('[', sym,
                                    newAst_VALUE (valueFromLit ((float) i))),
-                                   newAst_VALUE (valueFromLit (*s))));
-          s++;
+                                   newAst_VALUE (valueFromLit (*s++))));
         }
 
       // now WE don't need iexpr's symbol anymore
@@ -1185,7 +1226,7 @@ createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
   ast *iexpr;
 
   /* if deep then   */
-  if (ilist->type == INIT_DEEP)
+  if (ilist && ilist->type == INIT_DEEP)
     ilist = ilist->init.deep;
 
   iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
@@ -1206,7 +1247,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootVa
 {
   ast *rast = NULL;
 
-  if (!ilist)
+  if (!ilist && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (getSpec (type))))
     return NULL;
 
   /* if structure then    */
@@ -1234,7 +1275,8 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootVa
 /*-----------------------------------------------------------------*/
 /* initAggregates - initialises aggregate variables with initv     */
 /*-----------------------------------------------------------------*/
-ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
+ast * initAggregates (symbol * sym, initList * ival, ast * wid)
+{
   ast *newAst = newAst_VALUE (symbolVal (sym));
   return createIval (newAst, sym->type, ival, wid, newAst);
 }
@@ -1253,7 +1295,6 @@ gatherAutoInit (symbol * autoChain)
   inInitMode = 1;
   for (sym = autoChain; sym; sym = sym->next)
     {
-
       /* resolve the symbols in the ival */
       if (sym->ival)
         resolveIvalSym (sym->ival, sym->type);
@@ -1314,28 +1355,33 @@ gatherAutoInit (symbol * autoChain)
       /* if there is an initial value */
       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
         {
-          initList *ilist=sym->ival;
+          initList *ilist = sym->ival;
 
-          while (ilist->type == INIT_DEEP) {
-            ilist = ilist->init.deep;
-          }
+          while (ilist->type == INIT_DEEP)
+            {
+              ilist = ilist->init.deep;
+            }
 
           /* update lineno for error msg */
           filename = sym->fileDef;
           lineno = sym->lineDef;
           setAstFileLine (ilist->init.node, sym->fileDef, sym->lineDef);
 
-          if (IS_AGGREGATE (sym->type)) {
-            work = initAggregates (sym, sym->ival, NULL);
-          } else {
-            if (getNelements(sym->type, sym->ival)>1) {
-              werrorfl (sym->fileDef, sym->lineDef,
-                        W_EXCESS_INITIALIZERS, "scalar",
-                        sym->name);
+          if (IS_AGGREGATE (sym->type))
+            {
+              work = initAggregates (sym, sym->ival, NULL);
+            }
+          else
+            {
+              if (getNelements(sym->type, sym->ival)>1)
+                {
+                  werrorfl (sym->fileDef, sym->lineDef,
+                            W_EXCESS_INITIALIZERS, "scalar",
+                            sym->name);
+                }
+              work = newNode ('=', newAst_VALUE (symbolVal (sym)),
+                              list2expr (sym->ival));
             }
-            work = newNode ('=', newAst_VALUE (symbolVal (sym)),
-                            list2expr (sym->ival));
-          }
 
           // just to be sure
           setAstFileLine (work, sym->fileDef, sym->lineDef);
@@ -1452,7 +1498,6 @@ processBlockVars (ast * tree, int *stack, int action)
   return tree;
 }
 
-
 /*-------------------------------------------------------------*/
 /* constExprTree - returns TRUE if this tree is a constant     */
 /*                 expression                                  */
@@ -1791,8 +1836,8 @@ astHasDeref (ast * tree)
 }
 
 /*-----------------------------------------------------------------*/
-/* isConformingBody - the loop body has to conform to a set of rules */
-/* for the loop to be considered reversible read on for rules      */
+/* isConformingBody - the loop body has to conform to a set of     */
+/* rules for the loop to be considered reversible read on for rules*/
 /*-----------------------------------------------------------------*/
 bool
 isConformingBody (ast * pbody, symbol * sym, ast * body)
@@ -1801,14 +1846,13 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
   /* we are going to do a pre-order traversal of the
      tree && check for the following conditions. (essentially
      a set of very shallow tests )
-     a) the sym passed does not participate in
-     any arithmetic operation
+     a) the sym passed does not participate in any arithmetic operation
      b) There are no function calls
      c) all jumps are within the body
      d) address of loop control variable not taken
-     e) if an assignment has a pointer on the
-     left hand side make sure right does not have
-     loop control variable */
+     e) if an assignment has a pointer on the left hand side make sure
+        right does not have loop control variable
+  */
 
   /* if we reach the end or a leaf then true */
   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
@@ -1863,9 +1907,9 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 
       /* if right is NULL then unary operation  */
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*  address of                */
-/*----------------------------*/
+      /*----------------------------*/
       if (!pbody->right)
         {
           if (IS_AST_SYM_VALUE (pbody->left) &&
@@ -1965,7 +2009,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
       if (astHasVolatile (pbody->left))
         return FALSE;
 
-      if (astHasDeref(pbody->right)) return FALSE;
+      if (astHasDeref(pbody->right))
+        return FALSE;
 
       return isConformingBody (pbody->left, sym, body) &&
         isConformingBody (pbody->right, sym, body);
@@ -1982,27 +2027,31 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
       assert ("Parser should not have generated this\n");
 
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*      comma operator        */
-/*----------------------------*/
+      /*----------------------------*/
     case ',':
       return isConformingBody (pbody->left, sym, body) &&
         isConformingBody (pbody->right, sym, body);
 
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*       function call        */
-/*----------------------------*/
+      /*----------------------------*/
     case CALL:
-        /* if local & not passed as paramater then ok */
-        if (sym->level && !astHasSymbol(pbody->right,sym))
+        /* if local & not passed as parameter &
+           not used to find the function then ok */
+        if (sym->level && !astHasSymbol (pbody->right, sym) &&
+            !astHasSymbol (pbody->left, sym))
+          {
             return TRUE;
+          }
       return FALSE;
 
 /*------------------------------------------------------------------*/
-/*----------------------------*/
+      /*----------------------------*/
       /*     return statement       */
-/*----------------------------*/
+      /*----------------------------*/
     case RETURN:
       return FALSE;
 
@@ -2021,9 +2070,6 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 
   return isConformingBody (pbody->left, sym, body) &&
     isConformingBody (pbody->right, sym, body);
-
-
-
 }
 
 /*-----------------------------------------------------------------*/
@@ -2478,10 +2524,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
   /* just get the type        */
   if (tree->type == EX_VALUE)
     {
-
       if (IS_LITERAL (tree->opval.val->etype))
         {
-
           /* if this is a character array then declare it */
           if (IS_ARRAY (tree->opval.val->type))
             tree->opval.val = stringToSymbol (tree->opval.val);
@@ -3830,10 +3874,14 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       changePointer(LTYPE(tree));
       checkTypeSanity(LETYPE(tree), "(cast)");
 
-      /* if 'from' and 'to' are the same remove the superfluous cast, */
-      /* this helps other optimizations */
+
+      /* if 'from' and 'to' are the same remove the superfluous cast,
+       * this helps other optimizations */
       if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
         {
+          /* mark that the explicit cast has been removed,
+           * for proper processing (no integer promotion) of explicitly typecasted variable arguments */
+          tree->right->values.removedCast = 1;
           return tree->right;
         }
 
@@ -4149,9 +4197,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
                 if (!options.lessPedantic)
                   werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
                           ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
-                return decorateType (newAst_VALUE (constCharVal (
-                                   ccr_result == CCR_ALWAYS_TRUE ? 1 : 0)),
-                                                   resultType);
+                return decorateType (newAst_VALUE (constCharVal ((unsigned char)(ccr_result == CCR_ALWAYS_TRUE))), resultType);
               case CCR_OK:
               default:
                 break;
@@ -5957,8 +6003,6 @@ DEFSETFUNC (resetParmKey)
   return 1;
 }
 
-
-
 /*------------------------------------------------------------------*/
 /* fixupInlineLabel - change a label in an inlined function so that */
 /*                    it is always unique no matter how many times  */
@@ -5973,7 +6017,6 @@ fixupInlineLabel (symbol * sym)
   strcpy (sym->name, name);
 }
 
-
 /*------------------------------------------------------------------*/
 /* copyAstLoc - copy location information (file, line, block, etc.) */
 /*              from one ast node to another                        */
@@ -5986,10 +6029,8 @@ copyAstLoc (ast * dest, ast * src)
   dest->level = src->level;
   dest->block = src->block;
   dest->seqPoint = src->seqPoint;
-
 }
 
-
 /*-----------------------------------------------------------------*/
 /* fixupInline - perform various fixups on an inline function tree */
 /*               to take into account that it is no longer a       */
@@ -5998,13 +6039,13 @@ copyAstLoc (ast * dest, ast * src)
 static void
 fixupInline (ast * tree, int level)
 {
-  tree->block = currBlockno;
+  int savedBlockno = currBlockno;
 
   if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
     {
       symbol * decls;
 
-      currBlockno++;
+      currBlockno = ++blockNo;
       level++;
 
       /* Add any declared variables back into the symbol table */
@@ -6019,6 +6060,7 @@ fixupInline (ast * tree, int level)
     }
 
   tree->level = level;
+  tree->block = currBlockno;
 
   /* Update symbols */
   if (IS_AST_VALUE (tree) &&
@@ -6072,10 +6114,10 @@ fixupInline (ast * tree, int level)
       tree->right = gotoTree;
     }
 
-   /* Update any children */
-   if (tree->left)
+  /* Update any children */
+  if (tree->left)
       fixupInline (tree->left, level);
-   if (tree->right)
+  if (tree->right)
       fixupInline (tree->right, level);
 
   if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
@@ -6087,10 +6129,10 @@ fixupInline (ast * tree, int level)
       addSym (LabelTab, label, label->name, label->level, 0, 0);
     }
 
-
   if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
     {
       level--;
+      currBlockno = savedBlockno;
     }
 }
 
@@ -6127,7 +6169,6 @@ inlineAddDecl (symbol * sym, ast * block, int addSymTab)
     }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* inlineTempVar - create a temporary variable for inlining        */
 /*-----------------------------------------------------------------*/
@@ -6152,7 +6193,6 @@ inlineTempVar (sym_link * type, int level)
   return sym;
 }
 
-
 /*-----------------------------------------------------------------*/
 /* inlineFindParmRecurse - recursive function for inlineFindParm   */
 /*-----------------------------------------------------------------*/
@@ -6179,7 +6219,6 @@ inlineFindParmRecurse (ast * parms, int *index)
   return NULL;
 }
 
-
 /*-----------------------------------------------------------------*/
 /* inlineFindParm - search an ast tree of parameters to find one   */
 /*                  at a particular index (0=first parameter).     */
@@ -6191,33 +6230,6 @@ inlineFindParm (ast * parms, int index)
   return inlineFindParmRecurse (parms, &index);
 }
 
-/*-----------------------------------------------------------------*/
-/* inlineFindMaxBlockno - find maximum block number in an ast tree */
-/*-----------------------------------------------------------------*/
-static int
-inlineFindMaxBlockno (ast * tree, int maxBlockno)
-{
-  int tempBlockno;
-
-  if (!tree)
-    return maxBlockno;
-
-  tempBlockno = inlineFindMaxBlockno (tree->left, maxBlockno);
-  if (tempBlockno > maxBlockno)
-    maxBlockno = tempBlockno;
-
-  tempBlockno = inlineFindMaxBlockno (tree->right, maxBlockno);
-  if (tempBlockno > maxBlockno)
-    maxBlockno = tempBlockno;
-
-  if (tree->block > maxBlockno)
-    maxBlockno = tree->block;
-  return maxBlockno;
-}
-
-
-
-
 /*-----------------------------------------------------------------*/
 /* expandInlineFuncs - replace calls to inline functions with the  */
 /*                     function itself                             */
@@ -6277,19 +6289,13 @@ expandInlineFuncs (ast * tree, ast * block)
           /* during the function call. For example, a function         */
           /* declared as func(int x, int y) but called as func(y,x).   */
           /* { //inlinetree block                                      */
-          /*   type1 temparg1;                                         */
-          /*   ...                                                     */
-          /*   typen tempargn;                                         */
-          /*   temparg1 = argument1;                                   */
+          /*   type1 temparg1 = argument1;                             */
           /*   ...                                                     */
-          /*   tempargn = argumentn;                                   */
+          /*   typen tempargn = argumentn;                             */
           /*   { //inlinetree2 block                                   */
-          /*     type1 param1;                                         */
-          /*     ...                                                   */
-          /*     typen paramn;                                         */
-          /*     param1 = temparg1;                                    */
+          /*     type1 param1 = temparg1;                              */
           /*     ...                                                   */
-          /*     paramn = tempargn;                                    */
+          /*     typen paramn = tempargn;                              */
           /*     inline_function_code;                                 */
           /*     retlab:                                               */
           /*   }                                                       */
@@ -6299,32 +6305,39 @@ expandInlineFuncs (ast * tree, ast * block)
           while (args)
             {
               symbol * temparg;
-              ast * passedarg;
               ast * assigntree;
-              symbol * parm = copySymbol (args->sym);
+              symbol * parm;
+              ast * passedarg = inlineFindParm (tree->right, argIndex);
+
+              if (!passedarg)
+                {
+                  werror(E_TOO_FEW_PARMS);
+                  break;
+                }
 
               temparg = inlineTempVar (args->sym->type, tree->level+1);
               inlineAddDecl (temparg, inlinetree, FALSE);
 
-              passedarg = inlineFindParm (tree->right, argIndex);
               assigntree = newNode ('=',
                                     newAst_VALUE (symbolVal (temparg)),
                                     passedarg);
+              assigntree->initMode=1; // tell that assignment is initializer
               inlinetree->right = newNode (NULLOP,
                                            assigntree,
                                            inlinetree->right);
 
+              parm = copySymbol (args->sym);
               inlineAddDecl (parm, inlinetree2, FALSE);
               parm->_isparm = 0;
 
               assigntree = newNode ('=',
                                     newAst_VALUE (symbolVal (parm)),
                                     newAst_VALUE (symbolVal (temparg)));
+              assigntree->initMode=1; // tell that assignment is initializer
               inlinetree2->right = newNode (NULLOP,
                                            assigntree,
                                            inlinetree2->right);
 
-
               args = args->next;
               argIndex++;
             }
@@ -6364,7 +6377,6 @@ expandInlineFuncs (ast * tree, ast * block)
           fixupInline (inlinetree, inlinetree->level);
           inlineState.count++;
         }
-
     }
 
   /* Recursively continue to search for functions to inline. */
@@ -6380,7 +6392,6 @@ expandInlineFuncs (ast * tree, ast * block)
     }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* createFunction - This is the key node that calls the iCode for  */
 /*                  generating the code for a function. Note code  */
@@ -6395,7 +6406,6 @@ createFunction (symbol * name, ast * body)
   int stack = 0;
   sym_link *fetype;
   iCode *piCode = NULL;
-  int savedBlockno;
 
   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
@@ -6452,10 +6462,7 @@ createFunction (symbol * name, ast * body)
     reentrant++;
 
   inlineState.count = 0;
-  savedBlockno = currBlockno;
-  currBlockno = inlineFindMaxBlockno (body, 0);
   expandInlineFuncs (body, NULL);
-  currBlockno = savedBlockno;
 
   if (FUNC_ISINLINE (name->type))
     name->funcTree = copyAst (body);
@@ -6539,7 +6546,8 @@ skipall:
 
   /* we are done freeup memory & cleanup */
   noLineno--;
-  if (port->reset_labelKey) labelKey = 1;
+  if (port->reset_labelKey)
+    labelKey = 1;
   name->key = 0;
   FUNC_HASBODY(name->type) = 1;
   addSet (&operKeyReset, name);