From 35e8fec5cac35c8dcd3b96838e64c09484580146 Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Thu, 29 May 2008 08:49:00 +0000 Subject: [PATCH] * 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 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5186 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 9 ++ src/SDCCast.c | 171 +++++++++++++++++------------ src/SDCCval.c | 30 +++-- src/SDCCval.h | 3 +- support/regression/tests/zeropad.c | 40 ++++++- 5 files changed, 165 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef76487e..d3b63e1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-05-29 Maarten Brock + + * 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 * device/lib/pic16/startup/crt0.c, diff --git a/src/SDCCast.c b/src/SDCCast.c index a3cff8a4..4901b9a7 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -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; ietype) || 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); diff --git a/src/SDCCval.c b/src/SDCCval.c index 9a1b2537..649388f7 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -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)) { diff --git a/src/SDCCval.h b/src/SDCCval.h index 03b7dd13..61217835 100644 --- a/src/SDCCval.h +++ b/src/SDCCval.h @@ -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 diff --git a/support/regression/tests/zeropad.c b/support/regression/tests/zeropad.c index fef5ff50..24576a89 100644 --- a/support/regression/tests/zeropad.c +++ b/support/regression/tests/zeropad.c @@ -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 @@ -10,6 +11,10 @@ /* 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 @@ -20,11 +25,17 @@ 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 } -- 2.30.2