From: bernhardheld Date: Sun, 4 Jun 2006 20:14:11 +0000 (+0000) Subject: * src/SDCCval.c (checkConstantRange): added X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=aa0ca082f440cf7b9cf126faf97e03fbbf0c0bc2;p=fw%2Fsdcc * src/SDCCval.c (checkConstantRange): added * src/SDCCval.h: added checkConstantRange * support/Util/SDCCerr.c, * support/Util/SDCCerr.h: replaced unused W_IF_NEVER_TRUE and W_IF_ALWAYS_TRUE by W_COMP_RANGE and W_LIT_OVERFLOW * src/SDCC.y: moved early 'condition transformations' to SDCCast.c * src/SDCCast.c (decorateType): added checkConstantRange, added 'condition transformations' from SDCC.y so that now W_COMP_RANGE can be emitted with the correct always true/false warning, added optimization for double '!'; result of decorateType() must be assigned back to the tree, because decorateType() can change the tree * src/SDCCicode.c (geniCodeLogic), (geniCodeAssign): replaced new checkConstantRange, added warnings, (checkConstantRange): removed, it was only a fragment which never emitted a warning * src/SDCCsymt.c (computeType): fixed promotion for "-1 < (unsigned bit) b" * src/pic/ralloc.c (packRegsForAssign), * src/pic16/ralloc.c (packRegsForAssign), * src/hc08/ralloc.c (packRegsForAssign), * src/z80/ralloc.c (packRegsForAssign): ported fix for bug #930931 from mcs51 * src/mcs51/ralloc.c (packRegsForAssign): removed outcommented source * support/regression/tests/constantRange.c: added * support/valdiag/tests/constantRange.c: added git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4206 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index f2ff07e1..7491832e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2006-06-04 Bernhard Held + + * src/SDCCval.c (checkConstantRange): added + * src/SDCCval.h: added checkConstantRange + * support/Util/SDCCerr.c, + * support/Util/SDCCerr.h: replaced unused W_IF_NEVER_TRUE and + W_IF_ALWAYS_TRUE by W_COMP_RANGE and W_LIT_OVERFLOW + * src/SDCC.y: moved early 'condition transformations' to SDCCast.c + * src/SDCCast.c (decorateType): added checkConstantRange, + added 'condition transformations' from SDCC.y so that now W_COMP_RANGE + can be emitted with the correct always true/false warning, + added optimization for double '!'; + result of decorateType() must be assigned back to the tree, because + decorateType() can change the tree + * src/SDCCicode.c (geniCodeLogic), + (geniCodeAssign): replaced new checkConstantRange, added warnings, + (checkConstantRange): removed, it was only a fragment which never + emitted a warning + * src/SDCCsymt.c (computeType): fixed promotion for + "-1 < (unsigned bit) b" + * src/pic/ralloc.c (packRegsForAssign), + * src/pic16/ralloc.c (packRegsForAssign), + * src/hc08/ralloc.c (packRegsForAssign), + * src/z80/ralloc.c (packRegsForAssign): ported fix for bug #930931 + from mcs51 + * src/mcs51/ralloc.c (packRegsForAssign): removed outcommented source + * support/regression/tests/constantRange.c: added + * support/valdiag/tests/constantRange.c: added + 2006-06-02 Borut Razem * support/regression/ports/pic16/support.c: increase stack size diff --git a/src/SDCC.y b/src/SDCC.y index aae308d1..0277e533 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -334,40 +334,16 @@ shift_expr relational_expr : shift_expr - | relational_expr '<' shift_expr { - $$ = (port->lt_nge ? - newNode('!',newNode(GE_OP,$1,$3),NULL) : - newNode('<', $1,$3)); - } - | relational_expr '>' shift_expr { - $$ = (port->gt_nle ? - newNode('!',newNode(LE_OP,$1,$3),NULL) : - newNode('>',$1,$3)); - } - | relational_expr LE_OP shift_expr { - $$ = (port->le_ngt ? - newNode('!', newNode('>', $1 , $3 ), NULL) : - newNode(LE_OP,$1,$3)); - } - | relational_expr GE_OP shift_expr { - $$ = (port->ge_nlt ? - newNode('!', newNode('<', $1 , $3 ), NULL) : - newNode(GE_OP,$1,$3)); - } + | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);} + | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);} + | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);} + | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);} ; equality_expr : relational_expr - | equality_expr EQ_OP relational_expr { - $$ = (port->eq_nne ? - newNode('!',newNode(NE_OP,$1,$3),NULL) : - newNode(EQ_OP,$1,$3)); - } - | equality_expr NE_OP relational_expr { - $$ = (port->ne_neq ? - newNode('!', newNode(EQ_OP,$1,$3), NULL) : - newNode(NE_OP,$1,$3)); - } + | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);} + | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);} ; and_expr diff --git a/src/SDCCast.c b/src/SDCCast.c index dc745270..c0f85e9c 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -3492,6 +3492,20 @@ decorateType (ast * tree, RESULT_TYPE resultType) goto errorTreeReturn; } + /* if left is another '!' */ + if (tree->left->opval.op == '!') + { + /* remove double '!!X' by 'X ? 1 : 0' */ + tree->opval.op = '?'; + tree->left = tree->left->left; + tree->right = newNode (':', + newAst_VALUE (constVal ("1")), + newAst_VALUE (constVal ("0"))); + tree->right->lineno = tree->lineno; + tree->decorated = 0; + return decorateType (tree, resultType); + } + /* if left is a literal then do it */ if (IS_LITERAL (LTYPE (tree))) { @@ -3928,36 +3942,56 @@ decorateType (ast * tree, RESULT_TYPE resultType) } } - /* if unsigned value < 0 then always false */ + { + CCR_RESULT ccr_result = CCR_OK; + + /* if left is integral and right is literal + then check constant range */ + if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) + ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree), + tree->opval.op, FALSE); + if (ccr_result == CCR_OK && + IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) + ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree), + tree->opval.op, TRUE); + switch (ccr_result) + { + case CCR_ALWAYS_TRUE: + case CCR_ALWAYS_FALSE: + if (!options.lessPedantic) + werror (W_COMP_RANGE, + ccr_result == CCR_ALWAYS_TRUE ? "true" : "false"); + return decorateType (newAst_VALUE (constVal ( + ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")), + resultType); + case CCR_OK: + default: + break; + } + } + /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */ - if (SPEC_USIGN(LETYPE(tree)) && - !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */ + if (tree->opval.op == '>' && + SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) { - if (tree->opval.op == '<') + if (resultType == RESULT_TYPE_IFX) { - return tree->right; + /* the parent is an ifx: */ + /* if (unsigned value) */ + return tree->left; } - if (tree->opval.op == '>') - { - if (resultType == RESULT_TYPE_IFX) - { - /* the parent is an ifx: */ - /* if (unsigned value) */ - return tree->left; - } - /* (unsigned value) ? 1 : 0 */ - tree->opval.op = '?'; - tree->right = newNode (':', - newAst_VALUE (constVal ("1")), - tree->right); /* val 0 */ - tree->right->lineno = tree->lineno; - tree->right->left->lineno = tree->lineno; - tree->decorated = 0; - return decorateType (tree, resultType); - } + /* (unsigned value) ? 1 : 0 */ + tree->opval.op = '?'; + tree->right = newNode (':', + newAst_VALUE (constVal ("1")), + tree->right); /* val 0 */ + tree->right->lineno = tree->lineno; + tree->right->left->lineno = tree->lineno; + tree->decorated = 0; + return decorateType (tree, resultType); } /* 'ifx (op == 0)' -> 'ifx (!(op))' */ @@ -3986,6 +4020,7 @@ decorateType (ast * tree, RESULT_TYPE resultType) tree->opval.val->type); return tree; } + /* if one is 'signed char ' and the other one is 'unsigned char' */ /* it's necessary to promote to int */ if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) && @@ -4019,6 +4054,50 @@ decorateType (ast * tree, RESULT_TYPE resultType) LRVAL (tree) = RRVAL (tree) = 1; TTYPE (tree) = TETYPE (tree) = newBoolLink (); + + /* condition transformations */ + { + unsigned transformedOp = 0; + + switch (tree->opval.op) + { + case '<': /* transform (a < b) to !(a >= b) */ + if (port->lt_nge) + transformedOp = GE_OP; + break; + case '>': /* transform (a > b) to !(a <= b) */ + if (port->gt_nle) + transformedOp = LE_OP; + break; + case LE_OP: /* transform (a <= b) to !(a > b) */ + if (port->le_ngt) + transformedOp = '>'; + break; + case GE_OP: /* transform (a >= b) to !(a < b) */ + if (port->ge_nlt) + transformedOp = '<'; + break; + case NE_OP: /* transform (a != b) to !(a == b) */ + if (port->ne_neq) + transformedOp = EQ_OP; + break; + case EQ_OP: /* transform (a == b) to !(a != b) */ + if (port->eq_nne) + transformedOp = NE_OP; + break; + default: + break; + } + if (transformedOp) + { + tree->opval.op = transformedOp; + tree->decorated = 0; + tree = newNode ('!', tree, NULL); + tree->lineno = tree->left->lineno; + return decorateType (tree, resultType); + } + } + return tree; /*------------------------------------------------------------------*/ @@ -4480,9 +4559,12 @@ decorateType (ast * tree, RESULT_TYPE resultType) /*----------------------------*/ case FOR: - decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE); - decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE); - decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE); + AST_FOR (tree, initExpr) = decorateType ( + resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE); + AST_FOR (tree, condExpr) = decorateType ( + resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE); + AST_FOR (tree, loopExpr) = decorateType ( + resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE); /* if the for loop is reversible then reverse it otherwise do what we normally @@ -4562,6 +4644,15 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) if (!tree) return NULL; + /* while-loops insert a label between the IFX and the condition, + therefore look behind the label too */ + if (tree->opval.op == LABEL && + IS_ANDORNOT (tree->right)) + { + tree->right = backPatchLabels (tree->right, trueLabel, falseLabel); + return tree; + } + if (!(IS_ANDORNOT (tree))) return tree; diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 8ad10a8d..30af1cd4 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -127,88 +127,6 @@ iCodeTable codeTable[] = {SWAP, "swap", 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; - int warnings=0; - int negative=0; - long v; - - max = pow ((double)2.0, (double)bitsForType(ltype)); - - if (IS_LONG(val->type)) { - if (IS_UNSIGNED(val->type)) { - v=SPEC_CVAL(val->type).v_ulong; - } else { - v=SPEC_CVAL(val->type).v_long; - } - } else { - if (IS_UNSIGNED(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 (IS_FLOAT(ltype)) { - // anything will do - return; - } - - if (IS_FIXED(ltype)) { - // anything will do - return; - } - - if (!IS_UNSIGNED(val->type) && v<0) { - negative=1; - if (IS_UNSIGNED(ltype) && (pedantic>1)) { - warnings++; - } - v=-v; - } - - // if very pedantic: "char c=200" is not allowed - if (pedantic>1 && !IS_UNSIGNED(ltype)) { - max = max/2 + negative; - } - - if (v >= max) { - warnings++; - } - -#if 0 // temporary disabled, leaving the warning as a reminder - if (warnings) { - SNPRINTF (message, sizeof(message), "for %s %s in %s", - IS_UNSIGNED(ltype) ? "unsigned" : "signed", - nounName(ltype), msg); - werror (W_CONST_RANGE, message); - - if (pedantic>1) - fatalError++; - } -#endif -} - /*-----------------------------------------------------------------*/ /* operandName - returns the name of the operand */ /*-----------------------------------------------------------------*/ @@ -3010,8 +2928,17 @@ geniCodeLogic (operand * left, operand * right, int op) check if the literal value is within bounds */ if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype)) { - checkConstantRange(ltype, - OP_VALUE(right), "compare operation", 1); + CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE); + switch (ccr_result) + { + case CCR_ALWAYS_TRUE: + case CCR_ALWAYS_FALSE: + if (!options.lessPedantic) + werror (W_COMP_RANGE, "true resp. false"); + return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0); + default: + break; + } } /* if one operand is a pointer and the other is a literal generic void pointer, @@ -3228,10 +3155,11 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval) /* left is integral type and right is literal then check if the literal value is within bounds */ - if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) + if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) && + checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL && + !options.lessPedantic) { - checkConstantRange(ltype, - OP_VALUE(right), "= operation", 0); + werror (W_LIT_OVERFLOW); } /* if the left & right type don't exactly match */ diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 40e1fed6..9be6c7f5 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1966,12 +1966,12 @@ computeType (sym_link * type1, sym_link * type2, && ( (SPEC_USIGN (etype1) /* if this operand is promoted to a larger type, then it will be promoted to a signed type */ - && !(getSize (etype1) < getSize (reType)) + && !(bitsForType (etype1) < bitsForType (reType)) /* char require special handling */ && !IS_CHAR (etype1)) || /* same for 2nd operand */ (SPEC_USIGN (etype2) - && !(getSize (etype2) < getSize (reType)) + && !(bitsForType (etype2) < bitsForType (reType)) && !IS_CHAR (etype2)) || /* if both are 'unsigned char' and not promoted let the result be unsigned too */ diff --git a/src/SDCCval.c b/src/SDCCval.c index e278fb93..d8271ba8 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -367,6 +367,258 @@ cheapestVal (value *val) return (val); } +/*--------------------------------------------------------------------*/ +/* checkConstantRange - check if constant fits in numeric range of */ +/* var type in comparisons and assignments */ +/*--------------------------------------------------------------------*/ +CCR_RESULT +checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight) +{ + sym_link *reType; + double litVal; + int varBits; + + litVal = floatFromVal (valFromType (lit)); + varBits = bitsForType (var); + + /* sanity checks */ + if ( IS_FLOAT (var) + || IS_FIXED (var)) + return CCR_OK; + if (varBits < 1) + return CCR_ALWAYS_FALSE; + if (varBits > 32) + return CCR_ALWAYS_TRUE; + + /* special: assignment */ + if (op == '=') + { + if (IS_BIT (var)) + return CCR_OK; + + if (getenv ("SDCC_VERY_PEDANTIC")) + { + if (SPEC_USIGN (var)) + { + TYPE_UDWORD maxVal = 0xffffffffu >> (32 - varBits); + + if ( litVal < 0 + || litVal > maxVal) + return CCR_OVL; + return CCR_OK; + } + else + { + TYPE_DWORD minVal = 0xffffffff << (varBits - 1); + TYPE_DWORD maxVal = 0x7fffffff >> (32 - varBits); + + if ( litVal < minVal + || litVal > maxVal) + return CCR_OVL; + return CCR_OK; + } + } + else + { + /* ignore signedness, e.g. allow everything + from -127...+255 for (unsigned) char */ + TYPE_DWORD minVal = 0xffffffff << (varBits - 1); + TYPE_UDWORD maxVal = 0xffffffffu >> (32 - varBits); + + if ( litVal < minVal + || litVal > maxVal) + return CCR_OVL; + return CCR_OK; + } + } + + if (exchangeLeftRight) + switch (op) + { + case EQ_OP: break; + case NE_OP: break; + case '>': op = '<'; break; + case GE_OP: op = LE_OP; break; + case '<': op = '>'; break; + case LE_OP: op = GE_OP; break; + default: return CCR_ALWAYS_FALSE; + } + + reType = computeType (var, lit, RESULT_TYPE_NONE, op); + + if (SPEC_USIGN (reType)) + { + /* unsigned operation */ + TYPE_UDWORD minValP, maxValP, minValM, maxValM; + TYPE_UDWORD opBitsMask = 0xffffffffu >> (32 - bitsForType (reType)); + + if (SPEC_USIGN (lit) && SPEC_USIGN (var)) + { + /* both operands are unsigned, this is easy */ + minValP = 0; + maxValP = 0xffffffffu >> (32 - varBits); + /* there's only range, just copy it to 2nd set */ + minValM = minValP; + maxValM = maxValP; + } + else if (SPEC_USIGN (var)) + { + /* lit is casted from signed to unsigned, e.g.: + unsigned u; + u == (char) -17 + -> u == 0xffef' + */ + minValP = 0; + maxValP = 0xffffffffu >> (32 - varBits); + /* there's only one range, just copy it to 2nd set */ + minValM = minValP; + maxValM = maxValP; + + /* it's an unsigned operation */ + if ( IS_CHAR (reType) + || IS_INT (reType)) + { + /* make signed literal unsigned and + limit no of bits to size of return type */ + litVal = (TYPE_UDWORD) litVal & opBitsMask; + } + } + else /* SPEC_USIGN (lit) */ + { + /* var is casted from signed to unsigned, e.g.: + signed char c; + c == (unsigned) -17 + -> c == 0xffef' + + The possible values after casting var + split up in two, nonconsecutive ranges: + + minValP = 0; positive range: 0...127 + maxValP = 0x7f; + minValM = 0xff80; negative range: -128...-1 + maxValM = 0xffff; + */ + + /* positive range */ + minValP = 0; + maxValP = 0x7fffffffu >> (32 - varBits); + + /* negative range */ + minValM = 0xffffffff << (varBits - 1); + maxValM = 0xffffffffu; /* -1 */ + /* limit no of bits to size of return type */ + minValM &= opBitsMask; + maxValM &= opBitsMask; + } + + switch (op) + { + case EQ_OP: /* var == lit */ + if ( litVal <= maxValP + && litVal >= minValP) /* 0 */ + return CCR_OK; + if ( litVal <= maxValM + && litVal >= minValM) + return CCR_OK; + return CCR_ALWAYS_FALSE; + case NE_OP: /* var != lit */ + if ( litVal <= maxValP + && litVal >= minValP) /* 0 */ + return CCR_OK; + if ( litVal <= maxValM + && litVal >= minValM) + return CCR_OK; + return CCR_ALWAYS_TRUE; + case '>': /* var > lit */ + if (litVal >= maxValM) + return CCR_ALWAYS_FALSE; + if (litVal < minValP) /* 0 */ + return CCR_ALWAYS_TRUE; + return CCR_OK; + case GE_OP: /* var >= lit */ + if (litVal > maxValM) + return CCR_ALWAYS_FALSE; + if (litVal <= minValP) /* 0 */ + return CCR_ALWAYS_TRUE; + return CCR_OK; + case '<': /* var < lit */ + if (litVal > maxValM) + return CCR_ALWAYS_TRUE; + if (litVal <= minValP) /* 0 */ + return CCR_ALWAYS_FALSE; + return CCR_OK; + case LE_OP: /* var <= lit */ + if (litVal >= maxValM) + return CCR_ALWAYS_TRUE; + if (litVal < minValP) /* 0 */ + return CCR_ALWAYS_FALSE; + return CCR_OK; + default: + return CCR_ALWAYS_FALSE; + } + } + else + { + /* signed operation */ + TYPE_DWORD minVal, maxVal; + + if (SPEC_USIGN (var)) + { + /* unsigned var, but signed operation. This happens + when var is promoted to signed int. + Set actual min/max values of var. */ + minVal = 0; + maxVal = 0xffffffff >> (32 - varBits); + } + else + { + /* signed var */ + minVal = 0xffffffff << (varBits - 1); + maxVal = 0x7fffffff >> (32 - varBits); + } + + switch (op) + { + case EQ_OP: /* var == lit */ + if ( litVal > maxVal + || litVal < minVal) + return CCR_ALWAYS_FALSE; + return CCR_OK; + case NE_OP: /* var != lit */ + if ( litVal > maxVal + || litVal < minVal) + return CCR_ALWAYS_TRUE; + return CCR_OK; + case '>': /* var > lit */ + if (litVal >= maxVal) + return CCR_ALWAYS_FALSE; + if (litVal < minVal) + return CCR_ALWAYS_TRUE; + return CCR_OK; + case GE_OP: /* var >= lit */ + if (litVal > maxVal) + return CCR_ALWAYS_FALSE; + if (litVal <= minVal) + return CCR_ALWAYS_TRUE; + return CCR_OK; + case '<': /* var < lit */ + if (litVal > maxVal) + return CCR_ALWAYS_TRUE; + if (litVal <= minVal) + return CCR_ALWAYS_FALSE; + return CCR_OK; + case LE_OP: /* var <= lit */ + if (litVal >= maxVal) + return CCR_ALWAYS_TRUE; + if (litVal < minVal) + return CCR_ALWAYS_FALSE; + return CCR_OK; + default: + return CCR_ALWAYS_FALSE; + } + } +} + /*-----------------------------------------------------------------*/ /* valueFromLit - creates a value from a literal */ /*-----------------------------------------------------------------*/ diff --git a/src/SDCCval.h b/src/SDCCval.h index 906bc7e5..70054028 100644 --- a/src/SDCCval.h +++ b/src/SDCCval.h @@ -70,6 +70,16 @@ typedef struct initList } initList; +/* return values from checkConstantRange */ +typedef enum + { + CCR_OK, /* evaluate at runtime */ + CCR_OVL, + CCR_ALWAYS_FALSE, + CCR_ALWAYS_TRUE + } +CCR_RESULT; + #define IS_VARG(x) (x->vArgs) /* forward definitions for the symbol table related functions */ @@ -85,6 +95,7 @@ value *charVal (char *); value *symbolVal (symbol *); void printVal (value *); double floatFromVal (value *); +CCR_RESULT checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeOps); value *array2Ptr (value *); value *valUnaryPM (value *); value *valComplement (value *); diff --git a/src/hc08/ralloc.c b/src/hc08/ralloc.c index 13a4e2fc..2c40c925 100644 --- a/src/hc08/ralloc.c +++ b/src/hc08/ralloc.c @@ -1953,7 +1953,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) return 0; } - /* if the true symbol is defined in far space or on stack then we should not since this will increase register pressure */ #if 0 @@ -2028,16 +2027,18 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) return 0; /* did not find */ /* if assignment then check that right is not a bit */ - if (ASSIGNMENT (dic) && !POINTER_SET (dic)) + if (ASSIGNMENT (ic) && !POINTER_SET (ic)) { - sym_link *etype = operandType (IC_RIGHT (dic)); + sym_link *etype = operandType (IC_RESULT (dic)); if (IS_BITFIELD (etype)) { /* if result is a bit too then it's ok */ - etype = operandType (IC_RESULT (dic)); + etype = operandType (IC_RESULT (ic)); if (!IS_BITFIELD (etype)) - return 0; - } + { + return 0; + } + } } /* if the result is on stack or iaccess then it must be the same atleast one of the operands */ diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index ab4433ca..ce7dcea4 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -11662,7 +11662,7 @@ gen51Code (iCode * lic) case NE_OP: /* note these two are xlated by algebraic equivalence - during parsing SDCC.y */ + in decorateType() in SDCCast.c */ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "got '>=' or '<=' shouldn't have come here"); break; diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 82ff7c8d..972925da 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -2178,20 +2178,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } } } -#if 0 - /* if assignment then check that right is not a bit */ - if (ASSIGNMENT (dic) && !POINTER_SET (dic)) - { - sym_link *etype = operandType (IC_RIGHT (dic)); - if (IS_BITFIELD (etype)) - { - /* if result is a bit too then it's ok */ - etype = operandType (IC_RESULT (dic)); - if (!IS_BITFIELD (etype)) - return 0; - } - } -#endif + /* if the result is on stack or iaccess then it must be the same atleast one of the operands */ if (OP_SYMBOL (IC_RESULT (ic))->onStack || diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index 3281321b..d8b5d8df 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -3084,6 +3084,19 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (!dic) return 0; /* did not find */ + /* if assignment then check that right is not a bit */ + if (ASSIGNMENT (ic) && !POINTER_SET (ic)) + { + sym_link *etype = operandType (IC_RESULT (dic)); + if (IS_BITFIELD (etype)) + { + /* if result is a bit too then it's ok */ + etype = operandType (IC_RESULT (ic)); + if (!IS_BITFIELD (etype)) + return 0; + } + } + /* if the result is on stack or iaccess then it must be the same at least one of the operands */ if (OP_SYMBOL (IC_RESULT (ic))->onStack || diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index d14b83fb..c06b5daa 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -3181,12 +3181,12 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) * if it fits for pic16, but I leave it here just in case */ /* if assignment then check that right is not a bit */ - if (ASSIGNMENT (dic) && !POINTER_SET (dic)) { - sym_link *etype = operandType (IC_RIGHT (dic)); + if (ASSIGNMENT (ic) && !POINTER_SET (ic)) { + sym_link *etype = operandType (IC_RESULT (dic)); if (IS_BITFIELD (etype)) { /* if result is a bit too then it's ok */ - etype = operandType (IC_RESULT (dic)); + etype = operandType (IC_RESULT (ic)); if (!IS_BITFIELD (etype)) { debugLog(" %d bitfields\n"); return 0; diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index ca66aa9a..28a18be1 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -1748,6 +1748,21 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (!dic) return 0; /* did not find */ + /* if assignment then check that right is not a bit */ + if (ASSIGNMENT (ic) && !POINTER_SET (ic)) + { + sym_link *etype = operandType (IC_RESULT (dic)); + if (IS_BITFIELD (etype)) + { + /* if result is a bit too then it's ok */ + etype = operandType (IC_RESULT (ic)); + if (!IS_BITFIELD (etype)) + { + return 0; + } + } + } + /* if the result is on stack or iaccess then it must be the same atleast one of the operands */ if (OP_SYMBOL (IC_RESULT (ic))->onStack || diff --git a/support/Util/SDCCerr.c b/support/Util/SDCCerr.c index aa804d64..6839b417 100644 --- a/support/Util/SDCCerr.c +++ b/support/Util/SDCCerr.c @@ -237,8 +237,8 @@ struct "Functions called via pointers must be 'reentrant' to take arguments" }, { W_DOUBLE_UNSUPPORTED, ERROR_LEVEL_WARNING, "type 'double' not supported assuming 'float'" }, -{ W_IF_NEVER_TRUE, ERROR_LEVEL_WARNING, - "if-statement condition always false, if-statement not generated" }, +{ W_COMP_RANGE, ERROR_LEVEL_WARNING, + "comparison is always %s due to limited range of data type" }, { W_FUNC_NO_RETURN, ERROR_LEVEL_WARNING, "no 'return' statement found for function '%s'" }, { W_PRE_PROC_WARNING, ERROR_LEVEL_WARNING, @@ -367,8 +367,8 @@ struct "symbol name too long, truncated to %d chars" }, { W_CAST_STRUCT_PTR,ERROR_LEVEL_WARNING, "cast of struct %s * to struct %s * " }, -{ W_IF_ALWAYS_TRUE, ERROR_LEVEL_WARNING, - "if-statement condition always true, if-statement not generated" }, +{ W_LIT_OVERFLOW, ERROR_LEVEL_WARNING, + "overflow in implicit constant conversion" }, { E_PARAM_NAME_OMITTED, ERROR_LEVEL_ERROR, "in function %s: name omitted for parameter %d" }, { W_NO_FILE_ARG_IN_C1, ERROR_LEVEL_WARNING, diff --git a/support/Util/SDCCerr.h b/support/Util/SDCCerr.h index 64d1bb6b..c1e357ee 100644 --- a/support/Util/SDCCerr.h +++ b/support/Util/SDCCerr.h @@ -109,7 +109,7 @@ SDCCERR - SDCC Standard error handler #define E_EXTERN_MISMATCH 91 /* extern declaration mismatches */ #define W_NONRENT_ARGS 92 /* fptr non reentrant has args */ #define W_DOUBLE_UNSUPPORTED 93 /* 'double' not supported yet */ -#define W_IF_NEVER_TRUE 94 /* if always false */ +#define W_COMP_RANGE 94 /* comparison is always %s due to limited range of data type */ #define W_FUNC_NO_RETURN 95 /* no return statement found */ #define W_PRE_PROC_WARNING 96 /* preprocessor generated warning */ #define W_STRUCT_AS_ARG 97 /* structure passed as argument */ @@ -173,7 +173,7 @@ SDCCERR - SDCC Standard error handler #define W_PTR2INTEGRAL_NOCAST 155 #define W_SYMBOL_NAME_TOO_LONG 156 #define W_CAST_STRUCT_PTR 157 /* pointer to different structure types */ -#define W_IF_ALWAYS_TRUE 158 +#define W_LIT_OVERFLOW 158 /* overflow in implicit constant conversion */ #define E_PARAM_NAME_OMITTED 159 #define W_NO_FILE_ARG_IN_C1 160 #define E_NEED_OPT_O_IN_C1 161 diff --git a/support/valdiag/valdiag.py b/support/valdiag/valdiag.py index 0cf03703..370b8b81 100644 --- a/support/valdiag/valdiag.py +++ b/support/valdiag/valdiag.py @@ -28,7 +28,7 @@ macrodefs = {} gcc = { "CC":"gcc", - "CCFLAGS":"-c -Wall", + "CCFLAGS":"-c -Wall -DPORT_HOST=1", "CCDEF":"-D", "CCOUTPUT":"-o", "defined": {