X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=9e25e4367f0b7d68ed3bdc09f7e137faa595340f;hb=0299234dcc9718e0017d8a1a2d04c6b64220af2c;hp=1ab038c57aa3aa5a39f796cc727dd243caeaf2da;hpb=b4348b3bf4e04de567d99093298799b30a292f0d;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 1ab038c5..9e25e436 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -37,18 +37,25 @@ char *filename; int lineno; int block; int scopeLevel; -int lvaluereq; symbol *returnLabel; /* function return label */ symbol *entryLabel; /* function entry label */ + +#if defined(__BORLANDC__) || defined(_MSC_VER) +#define LONG_LONG __int64 +#else +#define LONG_LONG long long +#endif + /*-----------------------------------------------------------------*/ /* forward definition of some functions */ operand *geniCodeDivision (operand *, operand *); operand *geniCodeAssign (operand *, operand *, int); -operand *geniCodeArray (operand *, operand *); +operand *geniCodeArray (operand *, operand *,int); operand *geniCodeArray2Ptr (operand *); operand *geniCodeRValue (operand *, bool); -operand *geniCodeDerefPtr (operand *); +operand *geniCodeDerefPtr (operand *,int); +int isLvaluereq(int lvl); #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s) /* forward definition of ic print functions */ @@ -109,9 +116,66 @@ iCodeTable codeTable[] = {IFX, "if", picIfx, NULL}, {INLINEASM, "", picInline, NULL}, {RECEIVE, "recv", picReceive, NULL}, - {SEND, "send", picGenericOne, NULL} + {SEND, "send", picGenericOne, NULL}, + {ARRAYINIT, "arrayInit", picGenericOne, NULL}, }; +/*-----------------------------------------------------------------*/ +/* checkConstantRange: check a constant against the type */ +/*-----------------------------------------------------------------*/ + +/* pedantic=0: allmost anything is allowed as long as the absolute + value is within the bit range of the type, and -1 is treated as + 0xf..f for unsigned types (e.g. in assign) + pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare) + pedantic>1: "char c=200" is not allowed (evaluates to -56) +*/ + +void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) { + LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype); + char message[132]=""; + int warnings=0; + int negative=0; + long v=SPEC_CVAL(val->type).v_long; + +#if 0 + // this could be a good idea + if (options.pedantic) + pedantic=2; +#endif + + if (SPEC_NOUN(ltype)==FLOAT) { + // anything will do + return; + } + + if (!SPEC_USIGN(val->type) && v<0) { + negative=1; + if (SPEC_USIGN(ltype) && (pedantic>1)) { + warnings++; + } + v=-v; + } + + // if very pedantic: "char c=200" is not allowed + if (pedantic>1 && !SPEC_USIGN(ltype)) { + max = max/2 + negative; + } + + if (v >= max) { + warnings++; + } + + if (warnings) { + sprintf (message, "for %s %s in %s", + SPEC_USIGN(ltype) ? "unsigned" : "signed", + nounName(ltype), msg); + werror (W_CONST_RANGE, message); + + if (pedantic>1) + fatalError++; + } +} /*-----------------------------------------------------------------*/ /* operandName - returns the name of the operand */ @@ -146,12 +210,12 @@ printOperand (operand * op, FILE * file) case SYMBOL: #define REGA 1 #ifdef REGA - fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ + fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name), op->key, OP_LIVEFROM (op), OP_LIVETO (op), OP_SYMBOL (op)->stack, - op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat + op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc ); { fprintf (file, "{"); @@ -435,7 +499,7 @@ newOperand () { operand *op; - op = Safe_calloc (1, sizeof (operand)); + op = Safe_alloc ( sizeof (operand)); op->key = 0; return op; @@ -449,7 +513,7 @@ newiCode (int op, operand * left, operand * right) { iCode *ic; - ic = Safe_calloc (1, sizeof (iCode)); + ic = Safe_alloc ( sizeof (iCode)); ic->lineno = lineno; ic->filename = filename; @@ -473,6 +537,10 @@ newiCodeCondition (operand * condition, { iCode *ic; + if (IS_VOID(OP_SYMBOL(condition)->type)) { + werror(E_VOID_VALUE_USED); + } + ic = newiCode (IFX, NULL, NULL); IC_COND (ic) = condition; IC_TRUE (ic) = trueLabel; @@ -539,7 +607,7 @@ newiTempLabel (char *s) itmplbl->isitmp = 1; itmplbl->islbl = 1; itmplbl->key = labelKey++; - addSym (LabelTab, itmplbl, itmplbl->name, 0, 0); + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0); return itmplbl; } @@ -557,7 +625,7 @@ newiTempPreheaderLabel () itmplbl->isitmp = 1; itmplbl->islbl = 1; itmplbl->key = labelKey++; - addSym (LabelTab, itmplbl, itmplbl->name, 0, 0); + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0); return itmplbl; } @@ -610,6 +678,10 @@ copyiCode (iCode * ic) IC_INLINE (nic) = IC_INLINE (ic); break; + case ARRAYINIT: + IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic); + break; + default: IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic)); IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic)); @@ -839,11 +911,15 @@ operand * operandOperation (operand * left, operand * right, int op, sym_link * type) { + sym_link *let , *ret=NULL; operand *retval = (operand *) 0; - + assert (isOperandLiteral (left)); - if (right) + let = getSpec(operandType(left)); + if (right) { assert (isOperandLiteral (right)); + ret = getSpec(operandType(left)); + } switch (op) { @@ -875,22 +951,34 @@ operandOperation (operand * left, operand * right, operandLitValue (right))); break; case '%': - if ((unsigned long) operandLitValue (right) == 0) - { + if ((unsigned long) operandLitValue (right) == 0) { werror (E_DIVIDE_BY_ZERO); retval = right; - } - else - retval = operandFromLit ((unsigned long) operandLitValue (left) % - (unsigned long) operandLitValue (right)); + } + else + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) % + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); + break; case LEFT_OP: - retval = operandFromLit ((unsigned long) operandLitValue (left) << - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) << + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); break; case RIGHT_OP: - retval = operandFromLit ((unsigned long) operandLitValue (left) >> - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) >> + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); break; case EQ_OP: retval = operandFromLit (operandLitValue (left) == @@ -917,16 +1005,28 @@ operandOperation (operand * left, operand * right, operandLitValue (right)); break; case BITWISEAND: - retval = operandFromLit ((unsigned long) operandLitValue (left) & - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) & + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); break; case '|': - retval = operandFromLit ((unsigned long) operandLitValue (left) | - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) | + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); break; case '^': - retval = operandFromLit ((unsigned long) operandLitValue (left) ^ - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) ^ + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); break; case AND_OP: retval = operandFromLit (operandLitValue (left) && @@ -938,7 +1038,7 @@ operandOperation (operand * left, operand * right, break; case RRC: { - long i = operandLitValue (left); + long i = (long) operandLitValue (left); retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | (i << 1)); @@ -946,7 +1046,7 @@ operandOperation (operand * left, operand * right, break; case RLC: { - long i = operandLitValue (left); + long i = (long) operandLitValue (left); retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | (i >> 1)); @@ -1005,7 +1105,7 @@ isOperandEqual (operand * left, operand * right) return (floatFromVal (left->operand.valOperand) == floatFromVal (right->operand.valOperand)); case TYPE: - if (checkType (left->operand.typeOperand, + if (compareType (left->operand.typeOperand, right->operand.typeOperand) == 1) return 1; } @@ -1013,9 +1113,9 @@ isOperandEqual (operand * left, operand * right) return 0; } -/*-----------------------------------------------------------------*/ -/* isiCodeEqual - comapres two iCodes are returns true if yes */ -/*-----------------------------------------------------------------*/ +/*-------------------------------------------------------------------*/ +/* isiCodeEqual - compares two iCodes are equal, returns true if yes */ +/*-------------------------------------------------------------------*/ int isiCodeEqual (iCode * left, iCode * right) { @@ -1049,6 +1149,7 @@ isiCodeEqual (iCode * left, iCode * right) if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) return 0; } + return 1; } return 0; @@ -1073,7 +1174,6 @@ newiTempFromOp (operand * op) nop->isvolatile = op->isvolatile; nop->isGlobal = op->isGlobal; nop->isLiteral = op->isLiteral; - nop->noSpilLoc = op->noSpilLoc; nop->usesDefs = op->usesDefs; nop->isParm = op->isParm; return nop; @@ -1096,7 +1196,6 @@ operandFromOperand (operand * op) nop->isvolatile = op->isvolatile; nop->isGlobal = op->isGlobal; nop->isLiteral = op->isLiteral; - nop->noSpilLoc = op->noSpilLoc; nop->usesDefs = op->usesDefs; nop->isParm = op->isParm; @@ -1166,7 +1265,9 @@ operandFromSymbol (symbol * sym) /* under the following conditions create a register equivalent for a local symbol */ if (sym->level && sym->etype && SPEC_OCLS (sym->etype) && - (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) && + (IN_FARSPACE (SPEC_OCLS (sym->etype)) && + /* (!TARGET_IS_DS390)) && */ + (!(options.model == MODEL_FLAT24)) ) && options.stackAuto == 0) ok = 0; @@ -1278,7 +1379,7 @@ operandFromLink (sym_link * type) /* operandFromLit - makes an operand from a literal value */ /*-----------------------------------------------------------------*/ operand * -operandFromLit (float i) +operandFromLit (double i) { return operandFromValue (valueFromLit (i)); } @@ -1287,7 +1388,7 @@ operandFromLit (float i) /* operandFromAst - creates an operand from an ast */ /*-----------------------------------------------------------------*/ operand * -operandFromAst (ast * tree) +operandFromAst (ast * tree,int lvl) { if (!tree) @@ -1297,7 +1398,7 @@ operandFromAst (ast * tree) switch (tree->type) { case EX_OP: - return ast2iCode (tree); + return ast2iCode (tree,lvl+1); break; case EX_VALUE: @@ -1391,7 +1492,7 @@ usualUnaryConversions (operand * op) { if (IS_INTEGRAL (operandType (op))) { - if (getSize (operandType (op)) < INTSIZE) + if (getSize (operandType (op)) < (unsigned int) INTSIZE) { /* Widen to int. */ return geniCodeCast (INTTYPE, op, TRUE); @@ -1451,7 +1552,9 @@ geniCodeRValue (operand * op, bool force) if (IS_SPEC (type) && IS_TRUE_SYMOP (op) && - (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390)) + (!IN_FARSPACE (SPEC_OCLS (etype)) || + /* TARGET_IS_DS390)) */ + (options.model == MODEL_FLAT24) )) { op = operandFromOperand (op); op->isaddr = 0; @@ -1488,6 +1591,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) sym_link *optype; sym_link *opetype = getSpec (optype = operandType (op)); sym_link *restype; + int errors=0; /* one of them has size zero then error */ if (IS_VOID (optype)) @@ -1497,7 +1601,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) } /* if the operand is already the desired type then do nothing */ - if (checkType (type, optype) == 1) + if (compareType (type, optype) == 1) return op; /* if this is a literal then just change the type & return */ @@ -1505,20 +1609,69 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) return operandFromValue (valCastLiteral (type, operandLitValue (op))); - /* if casting to some pointer type && - the destination is not a generic pointer - then give a warning : (only for implicit casts) */ - if (IS_PTR (optype) && implicit && - (DCL_TYPE (optype) != DCL_TYPE (type)) && - !IS_GENPTR (type)) - { - werror (E_INCOMPAT_CAST); - werror (E_CONTINUE, "from type '"); - printTypeChain (optype, stderr); - fprintf (stderr, "' to type '"); - printTypeChain (type, stderr); - fprintf (stderr, "'\n"); + /* if casting to/from pointers, do some checking */ + if (IS_PTR(type)) { // to a pointer + if (!IS_PTR(optype) && !IS_FUNC(optype)) { // from a non pointer + if (IS_INTEGRAL(optype)) { + // maybe this is NULL, than it's ok. + if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) { + if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) { + // no way to set the storage + if (IS_LITERAL(optype)) { + werror(E_LITERAL_GENERIC); + errors++; + } else { + werror(E_NONPTR2_GENPTR); + errors++; + } + } else if (implicit) { + werror(W_INTEGRAL2PTR_NOCAST); + errors++; + } + } + } else { + // shouldn't do that with float, array or structure unless to void + if (!IS_VOID(getSpec(type)) && + !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { + werror(E_INCOMPAT_TYPES); + errors++; + } + } + } else { // from a pointer to a pointer + if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) { + // if not a pointer to a function + if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { + if (implicit) { // if not to generic, they have to match + if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) { + werror(E_INCOMPAT_PTYPES); + errors++; + } + } + } + } + } + } else { // to a non pointer + if (IS_PTR(optype)) { // from a pointer + if (implicit) { // sneaky + if (IS_INTEGRAL(type)) { + werror(W_PTR2INTEGRAL_NOCAST); + errors++; + } else { // shouldn't do that with float, array or structure + werror(E_INCOMPAT_TYPES); + errors++; + } + } } + } + if (errors) { + /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name, + implicit?"(implicit)":"", errors); */ + fprintf (stderr, "from type '"); + printTypeChain (optype, stderr); + fprintf (stderr, "' to type '"); + printTypeChain (type, stderr); + fprintf (stderr, "'\n"); + } /* if they are the same size create an assignment */ if (getSize (type) == getSize (optype) && @@ -1607,7 +1760,6 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt) if (resultIsInt) { SPEC_NOUN(getSpec(resType))=V_INT; - SPEC_SHORT(getSpec(resType))=0; } /* if the right is a literal & power of 2 */ @@ -1617,7 +1769,7 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt) if port has 1 byte muldiv */ if (p2 && !IS_FLOAT (letype) && !((resultIsInt) && (getSize (resType) != getSize (ltype)) && - (port->muldiv.native_below == 1))) + (port->support.muldiv == 1))) { if ((resultIsInt) && (getSize (resType) != getSize (ltype))) { @@ -1662,8 +1814,9 @@ geniCodeDivision (operand * left, operand * right) if (IS_LITERAL (retype) && !IS_FLOAT (letype) && (p2 = powof2 ((unsigned long) - floatFromVal (right->operand.valOperand)))) - ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ + floatFromVal (right->operand.valOperand)))) { + ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ + } else { ic = newiCode ('/', left, right); /* normal division */ @@ -1785,7 +1938,7 @@ geniCodeSubtract (operand * left, operand * right) /* geniCodeAdd - generates iCode for addition */ /*-----------------------------------------------------------------*/ operand * -geniCodeAdd (operand * left, operand * right) +geniCodeAdd (operand * left, operand * right,int lvl) { iCode *ic; sym_link *resType; @@ -1795,7 +1948,7 @@ geniCodeAdd (operand * left, operand * right) /* if left is an array then array access */ if (IS_ARRAY (ltype)) - return geniCodeArray (left, right); + return geniCodeArray (left, right,lvl); /* if the right side is LITERAL zero */ /* return the left side */ @@ -1907,7 +2060,7 @@ geniCodeArray2Ptr (operand * op) /* geniCodeArray - array access */ /*-----------------------------------------------------------------*/ operand * -geniCodeArray (operand * left, operand * right) +geniCodeArray (operand * left, operand * right,int lvl) { iCode *ic; sym_link *ltype = operandType (left); @@ -1918,7 +2071,7 @@ geniCodeArray (operand * left, operand * right) { left = geniCodeRValue (left, FALSE); } - return geniCodeDerefPtr (geniCodeAdd (left, right)); + return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl); } right = geniCodeMultiply (right, @@ -2005,10 +2158,10 @@ geniCodePostInc (operand * op) } rOp = newiTempOperand (rvtype, 0); - rOp->noSpilLoc = 1; + OP_SYMBOL(rOp)->noSpilLoc = 1; if (IS_ITEMP (rv)) - rv->noSpilLoc = 1; + OP_SYMBOL(rv)->noSpilLoc = 1; geniCodeAssign (rOp, rv, 0); @@ -2080,15 +2233,15 @@ geniCodePostDec (operand * op) /* if this is not an address we have trouble */ if (!op->isaddr) { - werror (E_LVALUE_REQUIRED, "++"); + werror (E_LVALUE_REQUIRED, "--"); return op; } rOp = newiTempOperand (rvtype, 0); - rOp->noSpilLoc = 1; + OP_SYMBOL(rOp)->noSpilLoc = 1; if (IS_ITEMP (rv)) - rv->noSpilLoc = 1; + OP_SYMBOL(rv)->noSpilLoc = 1; geniCodeAssign (rOp, rv, 0); @@ -2124,7 +2277,7 @@ geniCodePreDec (operand * op) if (!op->isaddr) { - werror (E_LVALUE_REQUIRED, "++"); + werror (E_LVALUE_REQUIRED, "--"); return op; } @@ -2256,7 +2409,7 @@ setOClass (sym_link * ptr, sym_link * spec) /* geniCodeDerefPtr - dereference pointer with '*' */ /*-----------------------------------------------------------------*/ operand * -geniCodeDerefPtr (operand * op) +geniCodeDerefPtr (operand * op,int lvl) { sym_link *rtype, *retype; sym_link *optype = operandType (op); @@ -2274,7 +2427,7 @@ geniCodeDerefPtr (operand * op) } /* now get rid of the pointer part */ - if (lvaluereq && IS_ITEMP (op)) + if (isLvaluereq(lvl) && IS_ITEMP (op)) { retype = getSpec (rtype = copyLinkChain (optype)); } @@ -2300,7 +2453,7 @@ geniCodeDerefPtr (operand * op) IS_CHAR (rtype) || IS_FLOAT (rtype)); - if (!lvaluereq) + if (!isLvaluereq(lvl)) op = geniCodeRValue (op, TRUE); setOperandType (op, rtype); @@ -2354,12 +2507,6 @@ geniCodeRightShift (operand * left, operand * right) return IC_RESULT (ic); } -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define LONG_LONG __int64 -#else -#define LONG_LONG long long -#endif - /*-----------------------------------------------------------------*/ /* geniCodeLogic- logic code */ /*-----------------------------------------------------------------*/ @@ -2373,13 +2520,10 @@ geniCodeLogic (operand * left, operand * right, int op) /* left is integral type and right is literal then check if the literal value is within bounds */ - if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype)) + if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype)) { - int nbits = bitsForType (ltype); - long v = operandLitValue (right); - - if (v > ((LONG_LONG) 1 << nbits) && v > 0) - werror (W_CONST_RANGE, " compare operation "); + checkConstantRange(ltype, + OP_VALUE(right), "compare operation", 1); } ctype = usualBinaryConversions (&left, &right); @@ -2418,19 +2562,19 @@ geniCodeUnary (operand * op, int oper) /* geniCodeConditional - geniCode for '?' ':' operation */ /*-----------------------------------------------------------------*/ operand * -geniCodeConditional (ast * tree) +geniCodeConditional (ast * tree,int lvl) { iCode *ic; symbol *falseLabel = newiTempLabel (NULL); symbol *exitLabel = newiTempLabel (NULL); - operand *cond = ast2iCode (tree->left); + operand *cond = ast2iCode (tree->left,lvl+1); operand *true, *false, *result; ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel); ADDTOCHAIN (ic); - true = ast2iCode (tree->right->left); + true = ast2iCode (tree->right->left,lvl+1); /* move the value to a new Operand */ result = newiTempOperand (operandType (true), 0); @@ -2442,7 +2586,7 @@ geniCodeConditional (ast * tree) /* now for the right side */ geniCodeLabel (falseLabel); - false = ast2iCode (tree->right->right); + false = ast2iCode (tree->right->right,lvl+1); geniCodeAssign (result, geniCodeRValue (false, FALSE), 0); /* create the exit label */ @@ -2471,11 +2615,8 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) check if the literal value is within bounds */ if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) { - int nbits = bitsForType (ltype); - long v = operandLitValue (right); - - if (v > ((LONG_LONG) 1 << nbits) && v > 0) - werror (W_CONST_RANGE, " = operation"); + checkConstantRange(ltype, + OP_VALUE(right), "= operation", 0); } /* if the left & right type don't exactly match */ @@ -2485,12 +2626,12 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) /* first check the type for pointer assignement */ if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) && - checkType (ltype, rtype) < 0) + compareType (ltype, rtype) < 0) { - if (checkType (ltype->next, rtype) < 0) + if (compareType (ltype->next, rtype) < 0) right = geniCodeCast (ltype->next, right, TRUE); } - else if (checkType (ltype, rtype) < 0) + else if (compareType (ltype, rtype) < 0) right = geniCodeCast (ltype, right, TRUE); /* if left is a true symbol & ! volatile @@ -2529,15 +2670,15 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) /* geniCodeSEParms - generate code for side effecting fcalls */ /*-----------------------------------------------------------------*/ static void -geniCodeSEParms (ast * parms) +geniCodeSEParms (ast * parms,int lvl) { if (!parms) return; if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeSEParms (parms->left); - geniCodeSEParms (parms->right); + geniCodeSEParms (parms->left,lvl); + geniCodeSEParms (parms->right,lvl); return; } @@ -2552,7 +2693,7 @@ geniCodeSEParms (ast * parms) parms->right->left->lvalue = 1; parms->opval.oprnd = - geniCodeRValue (ast2iCode (parms), FALSE); + geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); parms->type = EX_OPERAND; } @@ -2561,7 +2702,7 @@ geniCodeSEParms (ast * parms) /* geniCodeParms - generates parameters */ /*-----------------------------------------------------------------*/ static void -geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) +geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl) { iCode *ic; operand *pval; @@ -2572,8 +2713,8 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) /* if this is a param node then do the left & right */ if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeParms (parms->left, stack, fetype, func); - geniCodeParms (parms->right, stack, fetype, func); + geniCodeParms (parms->left, stack, fetype, func,lvl); + geniCodeParms (parms->right, stack, fetype, func,lvl); return; } @@ -2593,7 +2734,7 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) IS_ADDRESS_OF_OP (parms->right)) parms->right->left->lvalue = 1; - pval = geniCodeRValue (ast2iCode (parms), FALSE); + pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); } /* if register parm then make it a send */ @@ -2631,20 +2772,26 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) /* geniCodeCall - generates temp code for calling */ /*-----------------------------------------------------------------*/ operand * -geniCodeCall (operand * left, ast * parms) +geniCodeCall (operand * left, ast * parms,int lvl) { iCode *ic; operand *result; sym_link *type, *etype; int stack = 0; + if (!IS_FUNC(OP_SYMBOL(left)->type) && + !IS_CODEPTR(OP_SYMBOL(left)->type)) { + werror (E_FUNCTION_EXPECTED); + return NULL; + } + /* take care of parameters with side-effecting function calls in them, this is required to take care of overlaying function parameters */ - geniCodeSEParms (parms); + geniCodeSEParms (parms,lvl); /* first the parameters */ - geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left)); + geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl); /* now call : if symbol then pcall */ if (IS_OP_POINTER (left) || IS_ITEMP(left)) @@ -2690,7 +2837,8 @@ geniCodeReceive (value * args) if (IN_FARSPACE (SPEC_OCLS (sym->etype)) && options.stackAuto == 0 && - !TARGET_IS_DS390) + /* !TARGET_IS_DS390) */ + (!(options.model == MODEL_FLAT24)) ) { } else @@ -2719,7 +2867,7 @@ geniCodeReceive (value * args) /* geniCodeFunctionBody - create the function body */ /*-----------------------------------------------------------------*/ void -geniCodeFunctionBody (ast * tree) +geniCodeFunctionBody (ast * tree,int lvl) { iCode *ic; operand *func; @@ -2732,7 +2880,7 @@ geniCodeFunctionBody (ast * tree) iTempLblNum = 0; operandKey = 0; iCodeKey = 0; - func = ast2iCode (tree->left); + func = ast2iCode (tree->left,lvl+1); fetype = getSpec (operandType (func)); savelineno = lineno; @@ -2755,7 +2903,7 @@ geniCodeFunctionBody (ast * tree) geniCodeReceive (tree->values.args); /* generate code for the body */ - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); /* create a label for return */ geniCodeLabel (returnLabel); @@ -2786,10 +2934,10 @@ geniCodeReturn (operand * op) /* geniCodeIfx - generates code for extended if statement */ /*-----------------------------------------------------------------*/ void -geniCodeIfx (ast * tree) +geniCodeIfx (ast * tree,int lvl) { iCode *ic; - operand *condition = ast2iCode (tree->left); + operand *condition = ast2iCode (tree->left,lvl+1); sym_link *cetype; /* if condition is null then exit */ @@ -2838,7 +2986,7 @@ geniCodeIfx (ast * tree) } exit: - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ @@ -2936,10 +3084,10 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* geniCodeSwitch - changes a switch to a if statement */ /*-----------------------------------------------------------------*/ void -geniCodeSwitch (ast * tree) +geniCodeSwitch (ast * tree,int lvl) { iCode *ic; - operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE); + operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE); value *caseVals = tree->values.switchVals.swVals; symbol *trueLabel, *falseLabel; @@ -2977,7 +3125,7 @@ geniCodeSwitch (ast * tree) geniCodeGoto (falseLabel); jumpTable: - ast2iCode (tree->right); + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ @@ -2993,18 +3141,99 @@ geniCodeInline (ast * tree) ADDTOCHAIN (ic); } +/*-----------------------------------------------------------------*/ +/* geniCodeArrayInit - intermediate code for array initializer */ +/*-----------------------------------------------------------------*/ +static void +geniCodeArrayInit (ast * tree, operand *array) +{ + iCode *ic; + + if (!getenv("TRY_THE_NEW_INITIALIZER")) { + ic = newiCode (ARRAYINIT, array, NULL); + IC_ARRAYILIST (ic) = tree->values.constlist; + } else { + operand *left=newOperand(), *right=newOperand(); + left->type=right->type=SYMBOL; + OP_SYMBOL(left)=AST_SYMBOL(tree->left); + OP_SYMBOL(right)=AST_SYMBOL(tree->right); + ic = newiCode (ARRAYINIT, left, right); + } + ADDTOCHAIN (ic); +} + +/*-----------------------------------------------------------------*/ +/* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */ +/* particular case. Ie : assigning or dereferencing array or ptr */ +/*-----------------------------------------------------------------*/ +set * lvaluereqSet = NULL; +typedef struct lvalItem + { + int req; + int lvl; + } +lvalItem; + +/*-----------------------------------------------------------------*/ +/* addLvaluereq - add a flag for lvalreq for current ast level */ +/*-----------------------------------------------------------------*/ +void addLvaluereq(int lvl) +{ + lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem)); + lpItem->req=1; + lpItem->lvl=lvl; + addSetHead(&lvaluereqSet,lpItem); + +} +/*-----------------------------------------------------------------*/ +/* delLvaluereq - del a flag for lvalreq for current ast level */ +/*-----------------------------------------------------------------*/ +void delLvaluereq() +{ + lvalItem * lpItem; + lpItem = getSet(&lvaluereqSet); + if(lpItem) Safe_free(lpItem); +} +/*-----------------------------------------------------------------*/ +/* clearLvaluereq - clear lvalreq flag */ +/*-----------------------------------------------------------------*/ +void clearLvaluereq() +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) lpItem->req = 0; +} +/*-----------------------------------------------------------------*/ +/* getLvaluereq - get the last lvalreq level */ +/*-----------------------------------------------------------------*/ +int getLvaluereqLvl() +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) return lpItem->lvl; + return 0; +} +/*-----------------------------------------------------------------*/ +/* isLvaluereq - is lvalreq valid for this level ? */ +/*-----------------------------------------------------------------*/ +int isLvaluereq(int lvl) +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1))); + return 0; +} + /*-----------------------------------------------------------------*/ /* ast2iCode - creates an icodeList from an ast */ /*-----------------------------------------------------------------*/ operand * -ast2iCode (ast * tree) +ast2iCode (ast * tree,int lvl) { operand *left = NULL; operand *right = NULL; - if (!tree) return NULL; - /* set the global variables for filename & line number */ if (tree->filename) filename = tree->filename; @@ -3023,11 +3252,11 @@ ast2iCode (ast * tree) /* if we find a nullop */ if (tree->type == EX_OP && - (tree->opval.op == NULLOP || - tree->opval.op == BLOCK)) + (tree->opval.op == NULLOP || + tree->opval.op == BLOCK)) { - ast2iCode (tree->left); - ast2iCode (tree->right); + ast2iCode (tree->left,lvl+1); + ast2iCode (tree->right,lvl+1); return NULL; } @@ -3043,44 +3272,37 @@ ast2iCode (ast * tree) tree->opval.op != INLINEASM) { - if (IS_ASSIGN_OP (tree->opval.op) || - IS_DEREF_OP (tree) || - (tree->opval.op == '&' && !tree->right) || - tree->opval.op == PTR_OP) - { - lvaluereq++; - if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) || - (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left))) - { - int olvr = lvaluereq; - lvaluereq = 0; - left = operandFromAst (tree->left); - lvaluereq = olvr - 1; - } - else - { - left = operandFromAst (tree->left); - lvaluereq--; - } - if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left)) - left = geniCodeRValue (left, TRUE); - } - else - { - left = operandFromAst (tree->left); - } - if (tree->opval.op == INC_OP || - tree->opval.op == DEC_OP) - { - lvaluereq++; - right = operandFromAst (tree->right); - lvaluereq--; - } - else - { - right = operandFromAst (tree->right); - } - } + if (IS_ASSIGN_OP (tree->opval.op) || + IS_DEREF_OP (tree) || + (tree->opval.op == '&' && !tree->right) || + tree->opval.op == PTR_OP) + { + addLvaluereq(lvl); + if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) || + (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left))) + clearLvaluereq(); + + left = operandFromAst (tree->left,lvl); + delLvaluereq(); + if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left)) + left = geniCodeRValue (left, TRUE); + } + else + { + left = operandFromAst (tree->left,lvl); + } + if (tree->opval.op == INC_OP || + tree->opval.op == DEC_OP) + { + addLvaluereq(lvl); + right = operandFromAst (tree->right,lvl); + delLvaluereq(); + } + else + { + right = operandFromAst (tree->right,lvl); + } + } /* now depending on the type of operand */ /* this will be a biggy */ @@ -3089,12 +3311,13 @@ ast2iCode (ast * tree) case '[': /* array operation */ { - sym_link *ltype = operandType (left); - left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE); + //sym_link *ltype = operandType (left); + //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE); + left = geniCodeRValue (left, FALSE); right = geniCodeRValue (right, TRUE); } - return geniCodeArray (left, right); + return geniCodeArray (left, right,lvl); case '.': /* structure dereference */ if (IS_PTR (operandType (left))) @@ -3156,7 +3379,7 @@ ast2iCode (ast * tree) return geniCodeMultiply (geniCodeRValue (left, FALSE), geniCodeRValue (right, FALSE),IS_INT(tree->ftype)); else - return geniCodeDerefPtr (geniCodeRValue (left, FALSE)); + return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); case '-': if (right) @@ -3168,7 +3391,7 @@ ast2iCode (ast * tree) case '+': if (right) return geniCodeAdd (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE),lvl); else return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ @@ -3207,7 +3430,7 @@ ast2iCode (ast * tree) geniCodeRValue (right, FALSE), tree->opval.op); case '?': - return geniCodeConditional (tree); + return geniCodeConditional (tree,lvl); case SIZEOF: return operandFromLit (getSize (tree->right->ftype)); @@ -3217,7 +3440,7 @@ ast2iCode (ast * tree) sym_link *rtype = operandType (right); sym_link *ltype = operandType (left); if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && checkType (rtype->next, ltype) == 1) + && right->isaddr && compareType (rtype->next, ltype) == 1) right = geniCodeRValue (right, TRUE); else right = geniCodeRValue (right, FALSE); @@ -3249,7 +3472,7 @@ ast2iCode (ast * tree) sym_link *rtype = operandType (right); sym_link *ltype = operandType (left); if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && checkType (rtype->next, ltype) == 1) + && right->isaddr && compareType (rtype->next, ltype) == 1) right = geniCodeRValue (right, TRUE); else right = geniCodeRValue (right, FALSE); @@ -3258,14 +3481,14 @@ ast2iCode (ast * tree) return geniCodeAssign (left, geniCodeAdd (geniCodeRValue (operandFromOperand (left), FALSE), - right), 0); + right,lvl), 0); } case SUB_ASSIGN: { sym_link *rtype = operandType (right); sym_link *ltype = operandType (left); if (IS_PTR (rtype) && IS_ITEMP (right) - && right->isaddr && checkType (rtype->next, ltype) == 1) + && right->isaddr && compareType (rtype->next, ltype) == 1) { right = geniCodeRValue (right, TRUE); } @@ -3319,18 +3542,18 @@ ast2iCode (ast * tree) return geniCodeRValue (right, FALSE); case CALL: - return geniCodeCall (ast2iCode (tree->left), - tree->right); + return geniCodeCall (ast2iCode (tree->left,lvl+1), + tree->right,lvl); case LABEL: - geniCodeLabel (ast2iCode (tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand); + return ast2iCode (tree->right,lvl+1); case GOTO: - geniCodeGoto (ast2iCode (tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand); + return ast2iCode (tree->right,lvl+1); case FUNCTION: - geniCodeFunctionBody (tree); + geniCodeFunctionBody (tree,lvl); return NULL; case RETURN: @@ -3338,16 +3561,20 @@ ast2iCode (ast * tree) return NULL; case IFX: - geniCodeIfx (tree); + geniCodeIfx (tree,lvl); return NULL; case SWITCH: - geniCodeSwitch (tree); + geniCodeSwitch (tree,lvl); return NULL; case INLINEASM: geniCodeInline (tree); return NULL; + + case ARRAYINIT: + geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1)); + return NULL; } return NULL; @@ -3382,6 +3609,6 @@ iCodeFromAst (ast * tree) { returnLabel = newiTempLabel ("_return"); entryLabel = newiTempLabel ("_entry"); - ast2iCode (tree); + ast2iCode (tree,0); return reverseiCChain (); }