X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=5755fc38557d06ba07b0db25117ee26e7cd08394;hb=09d39698e1a6e80f55d7cd95f721e93811b00f1e;hp=919b9526267f06161ca4b4784cc2d0c6beaae5fd;hpb=f99d4b2c626ec803f1fb055b6cfa8a0807af1673;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 919b9526..5755fc38 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -40,6 +40,13 @@ 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 *); @@ -113,6 +120,62 @@ 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) { + 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 */ @@ -1515,6 +1578,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 +1596,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)) { // 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 +2494,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 +2507,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 +2602,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 */ @@ -3197,8 +3298,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); }