+2006-06-04 Bernhard Held <bernhard AT bernhardheld.de>
+
+ * 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 <borut.razem AT siol.net>
* support/regression/ports/pic16/support.c: increase stack size
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
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)))
{
}
}
- /* 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))' */
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)) &&
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;
/*------------------------------------------------------------------*/
/*----------------------------*/
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
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;
{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 */
/*-----------------------------------------------------------------*/
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,
/* 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 */
&& ( (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 */
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 */
/*-----------------------------------------------------------------*/
}
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 */
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 *);
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
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 */
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;
}
}
}
-#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 ||
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 ||
* 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;
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 ||
"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,
"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,
#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 */
#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
gcc = {
"CC":"gcc",
- "CCFLAGS":"-c -Wall",
+ "CCFLAGS":"-c -Wall -DPORT_HOST=1",
"CCDEF":"-D",
"CCOUTPUT":"-o",
"defined": {