* src/SDCCast.c (createIvalType, createIvalStruct, createIvalArray,
authorMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 29 May 2008 08:49:00 +0000 (08:49 +0000)
committerMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 29 May 2008 08:49:00 +0000 (08:49 +0000)
  createIvalCharPtr, createIvalPtr, createIval),
* src/SDCCval.h
* src/SDCCval.c (convertIListToConstList, list2expr): handle incomplete
  initializers for local auto variables
* support/regression/tests/zeropad.c: added testcase for auto initializers

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5186 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/SDCCast.c
src/SDCCval.c
src/SDCCval.h
support/regression/tests/zeropad.c

index ef76487eee73026462d709197cc151edc484cf3c..d3b63e1baf36116938a51df932774b81e7d693bd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-05-29 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * src/SDCCast.c (createIvalType, createIvalStruct, createIvalArray,
+         createIvalCharPtr, createIvalPtr, createIval),
+       * src/SDCCval.h
+       * src/SDCCval.c (convertIListToConstList, list2expr): handle incomplete
+         initializers for local auto variables
+       * support/regression/tests/zeropad.c: added testcase for auto initializers
+
 2008-05-26 Raphael Neider <rneider AT web.de>
 
        * device/lib/pic16/startup/crt0.c,
index a3cff8a4c5e5d5f77abd694c146614a2e3729eca..4901b9a75c5323e0509646edb40d1aea2129bccc 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)
@@ -961,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);
 }
 
@@ -978,28 +977,31 @@ 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)
@@ -1015,7 +1017,6 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
   return rast;
 }
 
-
 /*-----------------------------------------------------------------*/
 /* createIvalArray - generates code for array initialization       */
 /*-----------------------------------------------------------------*/
@@ -1026,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  */
@@ -1033,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);
@@ -1059,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))
@@ -1130,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))
@@ -1193,7 +1227,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);
@@ -1214,7 +1248,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    */
@@ -1242,7 +1276,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);
 }
@@ -1261,7 +1296,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);
@@ -1322,28 +1356,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);
@@ -1460,7 +1499,6 @@ processBlockVars (ast * tree, int *stack, int action)
   return tree;
 }
 
-
 /*-------------------------------------------------------------*/
 /* constExprTree - returns TRUE if this tree is a constant     */
 /*                 expression                                  */
@@ -5966,8 +6004,6 @@ DEFSETFUNC (resetParmKey)
   return 1;
 }
 
-
-
 /*------------------------------------------------------------------*/
 /* fixupInlineLabel - change a label in an inlined function so that */
 /*                    it is always unique no matter how many times  */
@@ -5982,7 +6018,6 @@ fixupInlineLabel (symbol * sym)
   strcpy (sym->name, name);
 }
 
-
 /*------------------------------------------------------------------*/
 /* copyAstLoc - copy location information (file, line, block, etc.) */
 /*              from one ast node to another                        */
@@ -5995,10 +6030,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       */
@@ -6082,10 +6115,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))
@@ -6097,7 +6130,6 @@ fixupInline (ast * tree, int level)
       addSym (LabelTab, label, label->name, label->level, 0, 0);
     }
 
-
   if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
     {
       level--;
@@ -6138,7 +6170,6 @@ inlineAddDecl (symbol * sym, ast * block, int addSymTab)
     }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* inlineTempVar - create a temporary variable for inlining        */
 /*-----------------------------------------------------------------*/
@@ -6163,7 +6194,6 @@ inlineTempVar (sym_link * type, int level)
   return sym;
 }
 
-
 /*-----------------------------------------------------------------*/
 /* inlineFindParmRecurse - recursive function for inlineFindParm   */
 /*-----------------------------------------------------------------*/
@@ -6190,7 +6220,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).     */
@@ -6364,7 +6393,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  */
@@ -6519,7 +6547,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);
index 9a1b2537c6bc9b80520fc6ccf738f936e1c3a1fb..649388f7f6e0c442cf0d15949e880495fe81a883 100644 (file)
@@ -53,7 +53,6 @@ newiList (int type, void *ilist)
 {
   initList *nilist;
 
-
   nilist = Safe_alloc (sizeof (initList));
 
   nilist->type = type;
@@ -75,7 +74,7 @@ newiList (int type, void *ilist)
 }
 
 /*------------------------------------------------------------------*/
-/* revinit   - reverses the initial values for a value  chain        */
+/* revinit   - reverses the initial values for a value chain        */
 /*------------------------------------------------------------------*/
 initList *
 revinit (initList * val)
@@ -100,19 +99,20 @@ revinit (initList * val)
 }
 
 bool
-convertIListToConstList(initList *src, literalList **lList)
+convertIListToConstList(initList *src, literalList **lList, int size)
 {
+    int cnt = 0;
     initList    *iLoop;
     literalList *head, *last, *newL;
 
     head = last = NULL;
 
-    if (!src || src->type != INIT_DEEP)
+    if (src && src->type != INIT_DEEP)
     {
         return FALSE;
     }
 
-    iLoop =  src->init.deep;
+    iLoop = src ? src->init.deep : NULL;
 
     while (iLoop)
     {
@@ -126,14 +126,19 @@ convertIListToConstList(initList *src, literalList **lList)
             return FALSE;
         }
         iLoop = iLoop->next;
+        cnt++;
+    }
+    if (!size)
+    {
+        size = cnt;
     }
 
     /* We've now established that the initializer list contains only literal values. */
 
-    iLoop = src->init.deep;
-    while (iLoop)
+    iLoop = src ? src->init.deep : NULL;
+    while (size--)
     {
-        double val = AST_FLOAT_VALUE(iLoop->init.node);
+        double val = iLoop ? AST_FLOAT_VALUE(iLoop->init.node) : 0;
 
         if (last && last->literalValue == val)
         {
@@ -156,7 +161,7 @@ convertIListToConstList(initList *src, literalList **lList)
             }
             last = newL;
         }
-        iLoop = iLoop->next;
+        iLoop = iLoop ? iLoop->next : NULL;
     }
 
     if (!head)
@@ -201,7 +206,7 @@ copyLiteralList(literalList *src)
 
 
 /*------------------------------------------------------------------*/
-/* copyIlist - copy initializer list            */
+/* copyIlist - copy initializer list                                */
 /*------------------------------------------------------------------*/
 initList *
 copyIlist (initList * src)
@@ -262,6 +267,8 @@ list2val (initList * val)
 ast *
 list2expr (initList * ilist)
 {
+  if (!ilist)
+    return NULL;
   if (ilist->type == INIT_DEEP)
     return list2expr (ilist->init.deep);
   return ilist->init.node;
@@ -1368,8 +1375,7 @@ valDiv (value * lval, value * rval)
 
   if (IS_FLOAT (val->type))
     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
-  else
-  if (IS_FIXED16X16 (val->type))
+  else if (IS_FIXED16X16 (val->type))
     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
   else if (SPEC_LONG (val->type))
     {
index 03b7dd138a1dfa8f05166678d9c222c4178795ee..61217835db23848e3b47236efe06e4d959df406a 100644 (file)
@@ -47,7 +47,6 @@ typedef struct value
     symbol *sym;                  /* Original Symbol                  */
     struct value *next;           /* used in initializer list         */
     unsigned vArgs:1;             /* arg list ended with variable arg */
-
   }
 value;
 
@@ -146,6 +145,6 @@ value *valForArray (struct ast *);
 value *valForStructElem (struct ast *, struct ast *);
 value *valForCastAggr (struct ast *, sym_link *, struct ast *, int);
 value *valForCastArr (struct ast * , sym_link *);
-bool convertIListToConstList(initList *src, literalList **lList);
+bool convertIListToConstList(initList *src, literalList **lList, int size);
 literalList *copyLiteralList(literalList *src);
 #endif
index fef5ff50f62b8e766c6af6cfb5f549dc5676a82a..24576a899adf241b2cbe74f19396751325d4a118 100644 (file)
@@ -1,8 +1,9 @@
 /** Zeropad tests.
 
-    storage: idata, pdata, xdata, code,
+    storage: auto, idata, pdata, xdata, code,
 */
 #ifndef STORAGE
+#define STORAGE_{storage}
 #define STORAGE {storage}
 #endif
 
   /* since g fails on GCC 2.95.4 on alpha... */
   #define FLEXARRAY 0
   #define TEST_G    0
+#elif defined (STORAGE_auto)
+  /* only static flexible arrays are allowed */
+  #define FLEXARRAY 0
+  #define TEST_G    1
 #else
   #define FLEXARRAY 1
   #define TEST_G    1
 typedef unsigned int size_t;
 #define offsetof(s,m)   (size_t)&(((s *)0)->m)
 
+#if defined (STORAGE_auto)
+  void Zeropad(void)
+  {
+#endif //STORAGE_auto
+
 const char *string1 = "\x00\x01";
 const char string2[] = "\x00\x01";
 
 #ifndef PORT_HOST
 #pragma disable_warning 147 //no warning about excess initializers (W_EXCESS_INITIALIZERS)
+#pragma disable_warning  85 //no warning about unreferenced variables (W_NO_REFERENCE)
 //array will be truncated but warning will be suppressed
 //if truncation is incorrect, other ASSERTs will fail with high probability
 char STORAGE trunc[2] = {'a', 'b', 'c'};
@@ -65,10 +76,14 @@ struct y STORAGE incompletestruct = {
 };
 #endif
 
-void
-testZeropad(void)
+#if !defined (STORAGE_auto)
+void Zeropad(void)
 {
+#endif //STORAGE_auto
+
+  ASSERT(string1[0] == '\x00');
   ASSERT(string1[1] == '\x01');
+  ASSERT(string2[0] == '\x00');
   ASSERT(string2[1] == '\x01');
 
   ASSERT(array[2] == 'c');
@@ -100,4 +115,23 @@ testZeropad(void)
   ASSERT(sizeof(incompletestruct) == offsetof(struct y, b));
   ASSERT(sizeof(incompletestruct) == offsetof(struct x, b));
 #endif
+
+#if defined (STORAGE_auto)
+  array[4] = 1;
+#if TEST_G
+  g[1].b = 1;
+#endif
+  teststruct[0].b[5] = 1;
+  teststruct[4].b[9] = 1;
+#endif //STORAGE_auto
+}
+
+void
+testZeropad(void)
+{
+  Zeropad();
+
+#if defined (STORAGE_auto)
+  Zeropad(); //test reinitialization
+#endif //STORAGE_auto
 }