{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 */
/*-----------------------------------------------------------------*/
/* signed and unsigned mul are the same, as long as the precision
of the result isn't bigger than the precision of the operands. */
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD) operandLitValue (left) *
- (TYPE_UDWORD) operandLitValue (right)));
+ (TYPE_TARGET_ULONG) operandLitValue (left) *
+ (TYPE_TARGET_ULONG) operandLitValue (right)));
else if (IS_UNSIGNED (type)) /* unsigned int */
{
/* unsigned int is handled here in order to detect overflow */
- TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
- (TYPE_UWORD) operandLitValue (right);
+ TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) operandLitValue (left) *
+ (TYPE_TARGET_UINT) operandLitValue (right);
- retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
- if (ul != (TYPE_UWORD) ul)
+ retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
+ if (ul != (TYPE_TARGET_UINT) ul)
werror (W_INT_OVL);
}
else /* signed int */
{
/* signed int is handled here in order to detect overflow */
- TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
- (TYPE_WORD) operandLitValue (right);
+ TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
+ (TYPE_TARGET_INT) operandLitValue (right);
- retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
- if (l != (TYPE_WORD) l)
+ retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
+ if (l != (TYPE_TARGET_INT) l)
werror (W_INT_OVL);
}
}
operandLitValue (right)));
break;
case '/':
- if ((TYPE_UDWORD) operandLitValue (right) == 0)
+ if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
{
werror (E_DIVIDE_BY_ZERO);
retval = right;
SPEC_USIGN (let) = 1;
SPEC_USIGN (ret) = 1;
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD) operandLitValue (left) /
- (TYPE_UDWORD) operandLitValue (right)));
+ (TYPE_TARGET_ULONG) operandLitValue (left) /
+ (TYPE_TARGET_ULONG) operandLitValue (right)));
}
else
{
}
break;
case '%':
- if ((TYPE_UDWORD) operandLitValue (right) == 0)
+ if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
{
werror (E_DIVIDE_BY_ZERO);
retval = right;
else
{
if (IS_UNSIGNED (type))
- retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
- (TYPE_UDWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) %
+ (TYPE_TARGET_ULONG) operandLitValue (right));
else
- retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
- (TYPE_DWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
+ (TYPE_TARGET_LONG) operandLitValue (right));
}
break;
case LEFT_OP:
/* The number of left shifts is always unsigned. Signed doesn't make
sense here. Shifting by a negative number is impossible. */
retval = operandFromValue (valCastLiteral (type,
- ((TYPE_UDWORD) operandLitValue (left) <<
- (TYPE_UDWORD) operandLitValue (right))));
+ ((TYPE_TARGET_ULONG) operandLitValue (left) <<
+ (TYPE_TARGET_ULONG) operandLitValue (right))));
break;
case RIGHT_OP:
/* The number of right shifts is always unsigned. Signed doesn't make
sense here. Shifting by a negative number is impossible. */
if (IS_UNSIGNED(let))
/* unsigned: logic shift right */
- retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
- (TYPE_UDWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) >>
+ (TYPE_TARGET_ULONG) operandLitValue (right));
else
/* signed: arithmetic shift right */
- retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
- (TYPE_UDWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_LONG ) operandLitValue (left) >>
+ (TYPE_TARGET_ULONG) operandLitValue (right));
break;
case EQ_OP:
if (IS_FLOAT (let) || IS_FLOAT (ret))
else
{
/* this op doesn't care about signedness */
- TYPE_UDWORD l, r;
+ TYPE_TARGET_ULONG l, r;
- l = (TYPE_UDWORD) operandLitValue (left);
- r = (TYPE_UDWORD) operandLitValue (right);
+ l = (TYPE_TARGET_ULONG) operandLitValue (left);
+ r = (TYPE_TARGET_ULONG) operandLitValue (right);
/* In order to correctly compare 'signed int' and 'unsigned int' it's
neccessary to strip them to 16 bit.
Literals are reduced to their cheapest type, therefore left and
if (!IS_LONG (let) &&
!IS_LONG (ret))
{
- r = (TYPE_UWORD) r;
- l = (TYPE_UWORD) l;
+ r = (TYPE_TARGET_UINT) r;
+ l = (TYPE_TARGET_UINT) l;
}
retval = operandFromLit (l == r);
}
break;
case BITWISEAND:
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD)operandLitValue(left) &
- (TYPE_UDWORD)operandLitValue(right)));
+ (TYPE_TARGET_ULONG)operandLitValue(left) &
+ (TYPE_TARGET_ULONG)operandLitValue(right)));
break;
case '|':
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD)operandLitValue(left) |
- (TYPE_UDWORD)operandLitValue(right)));
+ (TYPE_TARGET_ULONG)operandLitValue(left) |
+ (TYPE_TARGET_ULONG)operandLitValue(right)));
break;
case '^':
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD)operandLitValue(left) ^
- (TYPE_UDWORD)operandLitValue(right)));
+ (TYPE_TARGET_ULONG)operandLitValue(left) ^
+ (TYPE_TARGET_ULONG)operandLitValue(right)));
break;
case AND_OP:
retval = operandFromLit (operandLitValue (left) &&
break;
case RRC:
{
- TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
+ TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
(i << 1));
break;
case RLC:
{
- TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
+ TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
(i >> 1));
}
break;
case GETABIT:
- retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
- (TYPE_UDWORD)operandLitValue(right)) & 1);
+ retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
+ (TYPE_TARGET_ULONG)operandLitValue(right)) & 1);
break;
case GETBYTE:
- retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
- (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
+ retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
+ (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF);
break;
case GETWORD:
- retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
- (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
+ retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
+ (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF);
break;
case GETHBIT:
- retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
+ retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
((getSize (let) * 8) - 1)) & 1);
break;
case '~':
retval = operandFromValue (valCastLiteral (type,
- ~((TYPE_UDWORD)
+ ~((TYPE_TARGET_ULONG)
operandLitValue (left))));
break;
right->operand.valOperand));
if (IS_LITERAL(retype)) {
- p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
+ p2 = powof2 ((TYPE_TARGET_ULONG) floatFromVal (right->operand.valOperand));
}
resType = usualBinaryConversions (&left, &right, resultType, '*');
!IS_FLOAT (letype) &&
!IS_FIXED (letype) &&
IS_UNSIGNED(letype) &&
- ((p2 = powof2 ((TYPE_UDWORD)
+ ((p2 = powof2 ((TYPE_TARGET_ULONG)
floatFromVal (right->operand.valOperand))) > 0)) {
ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
}
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 */
" expected %s, got %s\n",
macro, args, file, line,
opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
- exit(-1);
+ exit(EXIT_FAILURE);
return op; // never reached, makes compiler happy.
}