X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=ecbe659b3b1d703ad5305ef7e390259a1cfb56a0;hb=58151142d861d5ddf8d0de65544016fe6fa7e3c0;hp=c5bc3f15eb8a77665fb0ac47d42c1598531d7ad5;hpb=3215b8241b93e48d217ffac784d64624dcd26eb3;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index c5bc3f15..ecbe659b 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -24,6 +24,7 @@ #include "common.h" #include "newalloc.h" +#include "math.h" /*-----------------------------------------------------------------*/ /* global variables */ @@ -40,6 +41,7 @@ int scopeLevel; symbol *returnLabel; /* function return label */ symbol *entryLabel; /* function entry label */ + /*-----------------------------------------------------------------*/ /* forward definition of some functions */ operand *geniCodeDivision (operand *, operand *); @@ -113,6 +115,79 @@ iCodeTable codeTable[] = {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) { + double max; + char message[132]=""; + int warnings=0; + int negative=0; + long v; + + max = pow ((double)2.0, (double)bitsForType(ltype)); + + if (SPEC_LONG(val->type)) { + if (SPEC_USIGN(val->type)) { + v=SPEC_CVAL(val->type).v_ulong; + } else { + v=SPEC_CVAL(val->type).v_long; + } + } else { + if (SPEC_USIGN(val->type)) { + v=SPEC_CVAL(val->type).v_uint; + } else { + v=SPEC_CVAL(val->type).v_int; + } + } + + +#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 */ @@ -436,7 +511,7 @@ newOperand () { operand *op; - op = Safe_calloc (1, sizeof (operand)); + op = Safe_alloc ( sizeof (operand)); op->key = 0; return op; @@ -450,7 +525,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; @@ -902,20 +977,20 @@ operandOperation (operand * left, operand * right, break; case LEFT_OP: - retval = operandFromLit (((SPEC_USIGN(let) ? + retval = operandFromLit ((SPEC_USIGN(let) ? (unsigned long) operandLitValue (left) : (long) operandLitValue (left)) << (SPEC_USIGN(ret) ? (unsigned long) operandLitValue (right) : - (long) operandLitValue (right)))); + (long) operandLitValue (right))); break; case RIGHT_OP: - retval = operandFromLit (((SPEC_USIGN(let) ? + retval = operandFromLit ((SPEC_USIGN(let) ? (unsigned long) operandLitValue (left) : (long) operandLitValue (left)) >> (SPEC_USIGN(ret) ? (unsigned long) operandLitValue (right) : - (long) operandLitValue (right)))); + (long) operandLitValue (right))); break; case EQ_OP: retval = operandFromLit (operandLitValue (left) == @@ -942,16 +1017,16 @@ operandOperation (operand * left, operand * right, operandLitValue (right)); break; case BITWISEAND: - retval = operandFromLit ((unsigned long) operandLitValue (left) & - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((long)operandLitValue(left) & + (long)operandLitValue(right)); break; case '|': - retval = operandFromLit ((unsigned long) operandLitValue (left) | - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((long)operandLitValue (left) | + (long)operandLitValue (right)); break; case '^': - retval = operandFromLit ((unsigned long) operandLitValue (left) ^ - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((long)operandLitValue (left) ^ + (long)operandLitValue (right)); break; case AND_OP: retval = operandFromLit (operandLitValue (left) && @@ -1038,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) { @@ -1074,6 +1149,7 @@ isiCodeEqual (iCode * left, iCode * right) if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) return 0; } + return 1; } return 0; @@ -1515,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)) @@ -1532,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); - fprintf (stderr, "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) && !IS_AGGREGATE(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) && @@ -2381,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 */ /*-----------------------------------------------------------------*/ @@ -2400,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 = (long) 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); @@ -2498,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 = (long) 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 */ @@ -2665,7 +2779,8 @@ geniCodeCall (operand * left, ast * parms,int lvl) sym_link *type, *etype; int stack = 0; - if (!IS_FUNC(OP_SYMBOL(left)->type)) { + if (!IS_FUNC(OP_SYMBOL(left)->type) && + !IS_CODEPTR(OP_SYMBOL(left)->type)) { werror (E_FUNCTION_EXPECTED); return NULL; } @@ -3034,8 +3149,16 @@ geniCodeArrayInit (ast * tree, operand *array) { iCode *ic; - ic = newiCode (ARRAYINIT, array, NULL); - IC_ARRAYILIST (ic) = tree->values.constlist; + 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); } @@ -3056,7 +3179,7 @@ lvalItem; /*-----------------------------------------------------------------*/ void addLvaluereq(int lvl) { - lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem)); + lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem)); lpItem->req=1; lpItem->lvl=lvl; addSetHead(&lvaluereqSet,lpItem); @@ -3069,7 +3192,7 @@ void delLvaluereq() { lvalItem * lpItem; lpItem = getSet(&lvaluereqSet); - if(lpItem) free(lpItem); + if(lpItem) Safe_free(lpItem); } /*-----------------------------------------------------------------*/ /* clearLvaluereq - clear lvalreq flag */ @@ -3188,8 +3311,9 @@ ast2iCode (ast * tree,int lvl) 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); }