X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=b3fb315863ed101885819d60acc4163522f3d24d;hb=8054f383bc887877947b3a056da737a546761fc2;hp=2c95c640a2adced67247922e069d7deb6dc82ffc;hpb=654bb877dab77c8752cbe0f8a6e3420de7275934;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 2c95c640..b3fb3158 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -24,6 +24,7 @@ #include "common.h" #include "newalloc.h" +#include "math.h" /*-----------------------------------------------------------------*/ /* global variables */ @@ -41,12 +42,6 @@ int scopeLevel; 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 *); @@ -131,11 +126,21 @@ iCodeTable codeTable[] = pedantic>1: "char c=200" is not allowed (evaluates to -56) */ -void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) { - LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype); +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)) { + v=SPEC_CVAL(val->type).v_long; + } else { + v=SPEC_CVAL(val->type).v_int; + } + #if 0 // this could be a good idea @@ -148,10 +153,9 @@ void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) { return; } - if (v<0) { + if (!SPEC_USIGN(val->type) && v<0) { negative=1; - // if not pedantic: -1 equals to 0xf..f - if (SPEC_USIGN(ltype) && (!pedantic ? v!=-1 : 1)) { + if (SPEC_USIGN(ltype) && (pedantic>1)) { warnings++; } v=-v; @@ -499,7 +503,7 @@ newOperand () { operand *op; - op = Safe_calloc (1, sizeof (operand)); + op = Safe_alloc ( sizeof (operand)); op->key = 0; return op; @@ -513,7 +517,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; @@ -923,6 +927,10 @@ operandOperation (operand * left, operand * right, switch (op) { + case '=': + // we need this now because of SDCCcse.c:1.52, it's a regression though + retval = right; + break; case '+': retval = operandFromValue (valCastLiteral (type, operandLitValue (left) + @@ -965,20 +973,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) == @@ -1005,16 +1013,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) && @@ -1101,9 +1109,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) { @@ -1137,6 +1145,7 @@ isiCodeEqual (iCode * left, iCode * right) if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) return 0; } + return 1; } return 0; @@ -1578,6 +1587,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)) @@ -1595,20 +1605,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 (W_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) && @@ -2460,7 +2519,7 @@ geniCodeLogic (operand * left, operand * right, int op) if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype)) { checkConstantRange(ltype, - operandLitValue(right), "compare operation", 1); + OP_VALUE(right), "compare operation", 1); } ctype = usualBinaryConversions (&left, &right); @@ -2553,7 +2612,7 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) { checkConstantRange(ltype, - operandLitValue(right), "= operation", 0); + OP_VALUE(right), "= operation", 0); } /* if the left & right type don't exactly match */ @@ -3116,7 +3175,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); @@ -3129,7 +3188,7 @@ void delLvaluereq() { lvalItem * lpItem; lpItem = getSet(&lvaluereqSet); - if(lpItem) free(lpItem); + if(lpItem) Safe_free(lpItem); } /*-----------------------------------------------------------------*/ /* clearLvaluereq - clear lvalreq flag */ @@ -3248,8 +3307,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); }