X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=0c512bbf8aee8eb104f1e0e2d87c81f110fe1465;hb=68f3891d9f67f419f8d6b14b16ea34ab8b137588;hp=4e2af8d76109a1fefec987c639e569607b9a1ca7;hpb=65149682a46ab8d47ca4de26570d2bcd1b3b1fc9;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 4e2af8d7..0c512bbf 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, double v, char *msg, int pedantic) { + LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype); + char message[132]=""; + int warnings=0; + int negative=0; + +#if 0 + // this could be a good idea + if (options.pedantic) + pedantic=2; +#endif + + if (SPEC_NOUN(ltype)==FLOAT) { + // anything will do + return; + } + + if (v<0) { + negative=1; + // if not pedantic: -1 equals to 0xf..f + if (SPEC_USIGN(ltype) && (!pedantic ? v!=-1 : 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 */ @@ -474,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; @@ -1511,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)) @@ -1528,20 +1596,64 @@ 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 (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(optype))) { + werror(E_INCOMPAT_TYPES); + errors++; + } + } + } else { // from a pointer to a pointer + 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) && @@ -2377,12 +2489,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 */ /*-----------------------------------------------------------------*/ @@ -2396,13 +2502,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, + operandLitValue(right), "compare operation", 1); } ctype = usualBinaryConversions (&left, &right); @@ -2494,11 +2597,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, + operandLitValue(right), "= operation", 0); } /* if the left & right type don't exactly match */ @@ -2661,6 +2761,12 @@ geniCodeCall (operand * left, ast * parms,int lvl) 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 */ @@ -3025,8 +3131,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); }