X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=4db1c15b6000e65ca99f3c446ae52214db7b6915;hb=7b0cd93b7bd04b332f409c2ece675f3943bbd70a;hp=85ea2852e1b4b6287e8297b2f2eb58e6fa71c9be;hpb=03b4af244de23fbad1574ec76a22305e4d7f91a0;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 85ea2852..4db1c15b 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -186,8 +186,7 @@ copyAstValues (ast * dest, ast * src) break; case INLINEASM: - dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1); - strcpy (dest->values.inlineasm, src->values.inlineasm); + dest->values.inlineasm = Safe_strdup(src->values.inlineasm); break; case ARRAYINIT: @@ -210,7 +209,7 @@ copyAstValues (ast * dest, ast * src) /* copyAst - makes a copy of a given astession */ /*-----------------------------------------------------------------*/ ast * -copyAst (ast * src) +copyAst (ast * src) { ast *dest; @@ -256,6 +255,31 @@ exit: } +/*-----------------------------------------------------------------*/ +/* removeIncDecOps: remove for side effects in *_ASSIGN's */ +/* "*s++ += 3" -> "*s++ = *s++ + 3" */ +/*-----------------------------------------------------------------*/ +ast *removeIncDecOps (ast * tree) { + + // traverse the tree and remove inc/dec ops + + if (!tree) + return NULL; + + if (tree->type == EX_OP && + (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) { + if (tree->left) + tree=tree->left; + else + tree=tree->right; + } + + tree->left=removeIncDecOps(tree->left); + tree->right=removeIncDecOps(tree->right); + + return tree; +} + /*-----------------------------------------------------------------*/ /* hasSEFcalls - returns TRUE if tree has a function call */ /*-----------------------------------------------------------------*/ @@ -342,6 +366,7 @@ resolveSymbols (ast * tree) if (tree == NULL) return tree; +#if 0 /* print the line */ /* if not block & function */ if (tree->type == EX_OP && @@ -352,6 +377,7 @@ resolveSymbols (ast * tree) filename = tree->filename; lineno = tree->lineno; } +#endif /* make sure we resolve the true & false labels for ifx */ if (tree->type == EX_OP && tree->opval.op == IFX) @@ -452,8 +478,7 @@ resolveChildren: /*-----------------------------------------------------------------*/ /* setAstLineno - walks a ast tree & sets the line number */ /*-----------------------------------------------------------------*/ -int -setAstLineno (ast * tree, int lineno) +int setAstLineno (ast * tree, int lineno) { if (!tree) return 0; @@ -480,7 +505,7 @@ funcOfType (char *name, sym_link * type, sym_link * argType, DCL_TYPE (sym->type) = FUNCTION; sym->type->next = copyLinkChain (type); sym->etype = getSpec (sym->type); - FUNC_ISREENT(sym->type) = rent; + FUNC_ISREENT(sym->type) = rent ? 1 : 0; /* if arguments required */ if (nArgs) @@ -641,7 +666,20 @@ processParms (ast * func, if (IS_INTEGRAL (ftype) && (getSize (ftype) < (unsigned) INTSIZE)) { - newType = newAst_LINK(INTTYPE); + if (IS_AST_OP(actParm) && + (actParm->opval.op == LEFT_OP || + actParm->opval.op == '*' || + actParm->opval.op == '+' || + actParm->opval.op == '-') && + actParm->right) { + // we should cast an operand instead of the result + actParm->decorated = 0; + actParm->left = newNode( CAST, newAst_LINK(newIntLink()), + actParm->left); + actParm = decorateType(actParm); + } else { + newType = newAst_LINK(INTTYPE); + } } if (IS_PTR(ftype) && !IS_GENPTR(ftype)) @@ -728,6 +766,7 @@ processParms (ast * func, /* 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); (*parmNumber)++; return 0; } @@ -925,6 +964,10 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) newNode ('[', sym, newAst_VALUE (valueFromLit ((float) i))), newAst_VALUE (valueFromLit (*s)))); + + // now WE don't need iexpr's symbol anymore + freeStringSymbol(AST_SYMBOL(iexpr)); + return decorateType (resolveSymbols (rast)); } @@ -1053,6 +1096,16 @@ gatherAutoInit (symbol * autoChain) /* if there is an initial value */ if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE) { + initList *ilist=sym->ival; + + while (ilist->type == INIT_DEEP) { + ilist = ilist->init.deep; + } + + /* update lineno for error msg */ + lineno=sym->lineDef; + setAstLineno (ilist->init.node, lineno); + if (IS_AGGREGATE (sym->type)) { work = initAggregates (sym, sym->ival, NULL); } else { @@ -1063,8 +1116,10 @@ gatherAutoInit (symbol * autoChain) work = newNode ('=', newAst_VALUE (symbolVal (sym)), list2expr (sym->ival)); } - + + // just to be sure setAstLineno (work, sym->lineDef); + sym->ival = NULL; if (init) init = newNode (NULLOP, init, work); @@ -1076,6 +1131,20 @@ gatherAutoInit (symbol * autoChain) return init; } +/*-----------------------------------------------------------------*/ +/* freeStringSymbol - delete a literal string if no more usage */ +/*-----------------------------------------------------------------*/ +void freeStringSymbol(symbol *sym) { + /* make sure this is a literal string */ + assert (sym->isstrlit); + if (--sym->isstrlit == 0) { // lower the usage count + memmap *segment=SPEC_OCLS(sym->etype); + if (segment) { + deleteSetItem(&segment->syms, sym); + } + } +} + /*-----------------------------------------------------------------*/ /* stringToSymbol - creates a symbol from a literal string */ /*-----------------------------------------------------------------*/ @@ -1085,10 +1154,22 @@ stringToSymbol (value * val) char name[SDCC_NAME_MAX + 1]; static int charLbl = 0; symbol *sym; + set *sp; + + // have we heard this before? + for (sp=statsg->syms; sp; sp=sp->next) { + sym=sp->item; + if (sym->isstrlit && + !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) { + // yes, this is old news. Don't publish it again. + sym->isstrlit++; // but raise the usage count + return symbolVal(sym); + } + } - sprintf (name, "_str_%d", charLbl++); + SNPRINTF (name, sizeof(name), "_str_%d", charLbl++); sym = newSymbol (name, 0); /* make it @ level 0 */ - strcpy (sym->rname, name); + strncpyz (sym->rname, name, SDCC_NAME_MAX); /* copy the type from the value passed */ sym->type = copyLinkChain (val->type); @@ -1170,6 +1251,10 @@ bool constExprTree (ast *cexpr) { // a function's address will never change return TRUE; } + if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) { + // an array's address will never change + return TRUE; + } if (IS_AST_SYM_VALUE(cexpr) && IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) { // a symbol in code space will never change @@ -1229,7 +1314,7 @@ constExprValue (ast * cexpr, int check) val->sym = cexpr->opval.val->sym; val->sym->type = copyLinkChain (cexpr->ftype); val->sym->etype = getSpec (val->sym->type); - strcpy (val->name, cexpr->opval.val->sym->rname); + strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX); return val; } @@ -1487,8 +1572,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) /* if we reach the end or a leaf then true */ if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody)) return TRUE; - - + /* if anything else is "volatile" */ if (IS_VOLATILE (TETYPE (pbody))) return FALSE; @@ -1499,6 +1583,10 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) { /*------------------------------------------------------------------*/ case '[': + // if the loopvar is used as an index + if (astHasSymbol(pbody->right, sym)) { + return FALSE; + } return isConformingBody (pbody->right, sym, body); /*------------------------------------------------------------------*/ @@ -1608,9 +1696,16 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) if (astHasVolatile (pbody->left)) return FALSE; - if (IS_AST_SYM_VALUE (pbody->left) && - isSymbolEqual (AST_SYMBOL (pbody->left), sym)) - return FALSE; + if (IS_AST_SYM_VALUE (pbody->left)) { + // if the loopvar has an assignment + if (isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; + // if the loopvar is used in another (maybe conditional) block + if (astHasSymbol (pbody->right, sym) && + (pbody->level > body->level)) { + return FALSE; + } + } if (astHasVolatile (pbody->left)) return FALSE; @@ -1760,14 +1855,15 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) rloop = newNode (NULLOP, createIf (newAst_VALUE (symbolVal (sym)), newNode (GOTO, - newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))), + newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))), NULL), NULL), newNode ('=', newAst_VALUE (symbolVal (sym)), end)); - + replLoopSym (loop->left, sym); - + setAstLineno (rloop, init->lineno); + rloop = newNode (NULLOP, newNode ('=', newAst_VALUE (symbolVal (sym)), @@ -1777,12 +1873,13 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) loop->left, newNode (NULLOP, newNode (SUB_ASSIGN, - newAst_VALUE (symbolVal (sym)), - newAst_VALUE (constVal ("1"))), + newAst_VALUE (symbolVal (sym)), + newAst_VALUE (constVal ("1"))), rloop)))); - + + rloop->lineno=init->lineno; return decorateType (rloop); - + } /*-----------------------------------------------------------------*/ @@ -1805,6 +1902,7 @@ decorateType (ast * tree) tree->decorated = 1; +#if 0 /* print the line */ /* if not block & function */ if (tree->type == EX_OP && @@ -1815,6 +1913,7 @@ decorateType (ast * tree) filename = tree->filename; lineno = tree->lineno; } +#endif /* if any child is an error | this one is an error do nothing */ if (tree->isError || @@ -1826,6 +1925,7 @@ decorateType (ast * tree) /*----------------------------*/ /* leaf has been reached */ /*----------------------------*/ + lineno=tree->lineno; /* if this is of type value */ /* just get the type */ if (tree->type == EX_VALUE) @@ -1898,6 +1998,26 @@ decorateType (ast * tree) tree->left = dtl; if (dtr != tree->right) tree->right = dtr; + + if (IS_AST_OP(tree) && + (tree->opval.op == CAST || tree->opval.op == '=') && + (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) && + (getSize(RTYPE(tree)) < INTSIZE)) { + // this is a cast/assign to a bigger type + if (IS_AST_OP(tree->right) && + IS_INTEGRAL(tree->right->ftype) && + (tree->right->opval.op == LEFT_OP || + tree->right->opval.op == '*' || + tree->right->opval.op == '+' || + tree->right->opval.op == '-') && + tree->right->right) { + // we should cast an operand instead of the result + tree->right->decorated = 0; + tree->right->left = newNode( CAST, newAst_LINK(newIntLink()), + tree->right->left); + tree->right = decorateType(tree->right); + } + } } /* depending on type of operator do */ @@ -1969,7 +2089,7 @@ decorateType (ast * tree) /*----------------------------*/ case PTR_OP: /* if not pointer to a structure */ - if (!IS_PTR (LTYPE (tree))) + if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree))) { werror (E_PTR_REQD); goto errorTreeReturn; @@ -2010,6 +2130,7 @@ decorateType (ast * tree) case UPOINTER: case ARRAY: case FUNCTION: + break; } return tree; @@ -2104,8 +2225,8 @@ decorateType (ast * tree) if (IS_FUNC (LTYPE (tree))) { - werror (E_ILLEGAL_ADDR, "address of function"); - goto errorTreeReturn; + // this ought to be ignored + return (tree->left); } if (IS_LITERAL(LTYPE(tree))) @@ -2162,6 +2283,7 @@ decorateType (ast * tree) ast *wtree = optimizeRRCRLC (tree); if (wtree != tree) return decorateType (wtree); + // fall through } /*------------------------------------------------------------------*/ /*----------------------------*/ @@ -2315,18 +2437,16 @@ decorateType (ast * tree) } LRVAL (tree) = RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + /* promote result to int if left & right are char this will facilitate hardware multiplies 8bit x 8bit = 16bit */ if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) { - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree))); SPEC_NOUN(TETYPE(tree)) = V_INT; - } else { - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree))); } + return tree; /*------------------------------------------------------------------*/ @@ -2410,7 +2530,7 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; /* if the left is a pointer */ - if (IS_PTR (LTYPE (tree))) + if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) ) TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); else @@ -2611,19 +2731,24 @@ decorateType (ast * tree) tree->opval.val->type); return tree; } + /* if only the right side is a literal & we are shifting more than size of the left operand then zero */ if (IS_LITERAL (RTYPE (tree)) && ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >= (getSize (LTYPE (tree)) * 8)) { - werror (W_SHIFT_CHANGED, - (tree->opval.op == LEFT_OP ? "left" : "right")); - tree->type = EX_VALUE; - tree->left = tree->right = NULL; - tree->opval.val = constVal ("0"); - TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; - return tree; + if (tree->opval.op==LEFT_OP || + (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) { + lineno=tree->lineno; + werror (W_SHIFT_CHANGED, + (tree->opval.op == LEFT_OP ? "left" : "right")); + tree->type = EX_VALUE; + tree->left = tree->right = NULL; + tree->opval.val = constVal ("0"); + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } } LRVAL (tree) = RRVAL (tree) = 1; if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree))) @@ -2681,12 +2806,16 @@ decorateType (ast * tree) LRVAL (tree) = 1; } #else +#if 0 // this is already checked, now this could be explicit /* if pointer to struct then check names */ if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) && IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) && - strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) { - werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag); - } + strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) + { + werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag, + SPEC_STRUCT(LETYPE(tree))->tag); + } +#endif /* if the right is a literal replace the tree */ if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) { tree->type = EX_VALUE; @@ -2766,10 +2895,17 @@ decorateType (ast * tree) /* if they are pointers they must be castable */ if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) { + if (tree->opval.op==EQ_OP && + !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) { + // we cannot cast a gptr to a !gptr: switch the leaves + struct ast *s=tree->left; + tree->left=tree->right; + tree->right=s; + } if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); - fprintf (stderr, "comparing type "); + fprintf (stderr, "comparring type "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, "to type "); printTypeChain (RTYPE (tree), stderr); @@ -2831,7 +2967,7 @@ decorateType (ast * tree) case SIZEOF: /* evaluate wihout code generation */ /* change the type to a integer */ tree->type = EX_VALUE; - sprintf (buffer, "%d", (getSize (tree->right->ftype))); + SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype))); tree->opval.val = constVal (buffer); tree->right = tree->left = NULL; TETYPE (tree) = getSpec (TTYPE (tree) = @@ -2904,7 +3040,7 @@ decorateType (ast * tree) break; } } - sprintf (buffer, "%d", typeofv); + SNPRINTF (buffer, sizeof(buffer), "%d", typeofv); tree->opval.val = constVal (buffer); tree->right = tree->left = NULL; TETYPE (tree) = getSpec (TTYPE (tree) = @@ -2946,6 +3082,7 @@ decorateType (ast * tree) return tree; +#if 0 // assignment operators are converted by the parser /*------------------------------------------------------------------*/ /*----------------------------*/ /* assignment operators */ @@ -3078,6 +3215,7 @@ decorateType (ast * tree) tree->opval.op = '='; return tree; +#endif /*------------------------------------------------------------------*/ /*----------------------------*/ @@ -3282,7 +3420,7 @@ sizeofOp (sym_link * type) checkTypeSanity(type, "(sizeof)"); /* get the size and convert it to character */ - sprintf (buff, "%d", getSize (type)); + SNPRINTF (buff, sizeof(buff), "%d", getSize (type)); /* now convert into value */ return constVal (buff); @@ -3316,7 +3454,7 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) static int localLbl = 0; symbol *localLabel; - sprintf (buffer, "_and_%d", localLbl++); + SNPRINTF(buffer, sizeof(buffer), "_and_%d", localLbl++); localLabel = newSymbol (buffer, NestLevel); tree->left = backPatchLabels (tree->left, localLabel, falseLabel); @@ -3342,7 +3480,7 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) static int localLbl = 0; symbol *localLabel; - sprintf (buffer, "_or_%d", localLbl++); + SNPRINTF(buffer, sizeof(buffer), "_or_%d", localLbl++); localLabel = newSymbol (buffer, NestLevel); tree->left = backPatchLabels (tree->left, trueLabel, localLabel); @@ -3434,7 +3572,7 @@ createLabel (symbol * label, ast * stmnt) label = newSymbol (label->name, label->level); /* change the name before putting it in add _ */ - sprintf (name, "%s", label->name); + SNPRINTF(name, sizeof(name), "%s", label->name); /* put the label in the LabelSymbol table */ /* but first check if a label of the same */ @@ -3522,7 +3660,8 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) } /* create the case label */ - sprintf (caseLbl, "_case_%d_%d", + SNPRINTF(caseLbl, sizeof(caseLbl), + "_case_%d_%d", swStat->values.switchVals.swNum, (int) floatFromVal (caseVal->opval.val)); @@ -3551,7 +3690,8 @@ createDefault (ast * swStat, ast * stmnt) swStat->values.switchVals.swDefault = 1; /* create the label */ - sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum); + SNPRINTF (defLbl, sizeof(defLbl), + "_default_%d", swStat->values.switchVals.swNum); return createLabel (newSymbol (defLbl, 0), stmnt); } @@ -3574,18 +3714,18 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody) } /* create the labels */ - sprintf (buffer, "_iffalse_%d", Lblnum); + SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum); ifFalse = newSymbol (buffer, NestLevel); /* if no else body then end == false */ if (!elseBody) ifEnd = ifFalse; else { - sprintf (buffer, "_ifend_%d", Lblnum); + SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum); ifEnd = newSymbol (buffer, NestLevel); } - sprintf (buffer, "_iftrue_%d", Lblnum); + SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum); ifTrue = newSymbol (buffer, NestLevel); Lblnum++; @@ -4217,7 +4357,7 @@ createFunction (symbol * name, ast * body) name->stack = SPEC_STAK (fetype) = stack; /* name needs to be mangled */ - sprintf (name->rname, "%s%s", port->fun_prefix, name->name); + SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name); body = resolveSymbols (body); /* resolve the symbols */ body = decorateType (body); /* propagateType & do semantic checks */