mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 15:29:46 +00:00
Merge pull request #1918 from acqn/PPFix
[cc65] Fixed bitwise-shift in preprocessor
This commit is contained in:
commit
a0a9cfdcd3
@ -519,12 +519,21 @@ static void PPhie7 (PPExpr* Expr)
|
||||
|
||||
/* Evaluate */
|
||||
if (PPEvaluationEnabled && !PPEvaluationFailed) {
|
||||
/* To shift by a negative value is equivalent to shift to the
|
||||
** opposite direction.
|
||||
*/
|
||||
if ((Rhs.Flags & PPEXPR_UNSIGNED) != 0 && Rhs.IVal > (long)LONG_BITS) {
|
||||
/* For now we use 32-bit integer types for PP integer constants */
|
||||
if ((Rhs.Flags & PPEXPR_UNSIGNED) != 0) {
|
||||
if ((unsigned long)Rhs.IVal > LONG_BITS) {
|
||||
Rhs.IVal = (long)LONG_BITS;
|
||||
}
|
||||
} else if (Rhs.IVal > (long)LONG_BITS) {
|
||||
Rhs.IVal = (long)LONG_BITS;
|
||||
} else if (Rhs.IVal < -(long)LONG_BITS) {
|
||||
Rhs.IVal = -(long)LONG_BITS;
|
||||
}
|
||||
|
||||
/* Positive count for left-shift and negative for right-shift. So
|
||||
** to shift by a count is equivalent to shift to the opposite
|
||||
** direction by the negated count.
|
||||
*/
|
||||
if (Op == TOK_SHR) {
|
||||
Rhs.IVal = -Rhs.IVal;
|
||||
}
|
||||
@ -532,27 +541,26 @@ static void PPhie7 (PPExpr* Expr)
|
||||
/* Evaluate the result */
|
||||
if ((Expr->Flags & PPEXPR_UNSIGNED) != 0) {
|
||||
if (Rhs.IVal >= (long)LONG_BITS) {
|
||||
/* For now we use (unsigned) long types for integer constants */
|
||||
PPWarning ("Integer overflow in preprocessor expression");
|
||||
Expr->IVal = 0;
|
||||
} else if (Rhs.IVal > 0) {
|
||||
Expr->IVal <<= Rhs.IVal;
|
||||
} else if (Rhs.IVal < -(long)LONG_BITS) {
|
||||
} else if (Rhs.IVal <= -(long)LONG_BITS) {
|
||||
Expr->IVal = 0;
|
||||
} else if (Rhs.IVal < 0) {
|
||||
Expr->IVal = (unsigned long)Expr->IVal >> -Rhs.IVal;
|
||||
}
|
||||
} else {
|
||||
/* -1 for sign bit */
|
||||
if (Rhs.IVal >= (long)(LONG_BITS - 1)) {
|
||||
/* For now we use (unsigned) long types for integer constants */
|
||||
PPWarning ("Integer overflow in preprocessor expression");
|
||||
Expr->IVal = 0;
|
||||
} else if (Rhs.IVal > 0) {
|
||||
Expr->IVal <<= Rhs.IVal;
|
||||
} else if (Rhs.IVal < -(long)LONG_BITS) {
|
||||
Expr->IVal = -1;
|
||||
} else if (Rhs.IVal <= -(long)LONG_BITS) {
|
||||
Expr->IVal = Expr->IVal >= 0 ? 0 : -1;
|
||||
} else if (Rhs.IVal < 0) {
|
||||
Expr->IVal >>= Expr->IVal >> -Rhs.IVal;
|
||||
Expr->IVal = (long)Expr->IVal >> -Rhs.IVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
120
test/val/ppshift.c
Normal file
120
test/val/ppshift.c
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
Test of bitwise-shift in preprocessor expressions.
|
||||
|
||||
Note: Keep in mind that integer constants are always 32-bit in PP for cc65.
|
||||
*/
|
||||
|
||||
/* Signed lhs */
|
||||
#if 1 << 16 != 0x00010000
|
||||
#error 1 << 16 != 0x00010000
|
||||
#endif
|
||||
|
||||
#if 0x00010000 << -16 != 1
|
||||
#error 0x00010000 << -16 != 1
|
||||
#endif
|
||||
|
||||
#if 0x10000 >> 16 != 1
|
||||
#error 0x10000 >> 16 != 1
|
||||
#endif
|
||||
|
||||
#if 1 >> -16 != 0x10000
|
||||
#error 1 >> -16 != 0x10000
|
||||
#endif
|
||||
|
||||
#if 1 << 32 != 0
|
||||
#error 1 << 32 != 0
|
||||
#endif
|
||||
|
||||
#if 1 << -32 != 0
|
||||
#error 1 << -32 != 0
|
||||
#endif
|
||||
|
||||
#if 1 >> 32 != 0
|
||||
#error 1 >> 32 != 0
|
||||
#endif
|
||||
|
||||
#if 1 >> -32 != 0
|
||||
#error 1 >> -32 != 0
|
||||
#endif
|
||||
|
||||
#if -1 << 32 != 0
|
||||
#error -1 << 32 != 0
|
||||
#endif
|
||||
|
||||
#if -1 << -32 != -1
|
||||
#error -1 << -32 != -1
|
||||
#endif
|
||||
|
||||
#if -1 >> 32 != -1
|
||||
#error -1 >> 32 != -1
|
||||
#endif
|
||||
|
||||
#if -1 >> -32 != 0
|
||||
#error -1 >> -32 != 0
|
||||
#endif
|
||||
|
||||
/* NOTE: 2147483648 is an UNSIGNED integer! */
|
||||
#if -1 << 2147483648 != 0
|
||||
#error -1 << 2147483648 != 0
|
||||
#endif
|
||||
|
||||
/* NOTE: -2147483648 is also an UNSIGNED integer! */
|
||||
#if -1 << -2147483648 != 0
|
||||
#error -1 << -2147483648 != 0
|
||||
#endif
|
||||
|
||||
#if -1 << (-2147483647 - 1) != -1
|
||||
#error -1 << (-2147483647 - 1) != -1
|
||||
#endif
|
||||
|
||||
/* NOTE: 2147483648 is an UNSIGNED integer! */
|
||||
#if -1 >> 2147483648 != -1
|
||||
#error -1 >> 2147483648 != -1
|
||||
#endif
|
||||
|
||||
/* NOTE: -2147483648 is also an UNSIGNED integer! */
|
||||
#if -1 >> -2147483648 != -1
|
||||
#error -1 >> -2147483648 != 0
|
||||
#endif
|
||||
|
||||
#if -1 >> (-2147483647 - 1) != 0
|
||||
#error -1 >> (-2147483647 - 1) != 0
|
||||
#endif
|
||||
|
||||
/* Unsigned lhs */
|
||||
#if 1U << 16 != 0x00010000
|
||||
#error 1U << 16 != 0x00010000
|
||||
#endif
|
||||
|
||||
#if 0x80000000U << -16 != 0x8000
|
||||
#error 0x80000000U << -16 != 0x8000
|
||||
#endif
|
||||
|
||||
#if 0x80000000U >> 16 != 0x8000
|
||||
#error 0x80000000U >> 16 != 0x8000
|
||||
#endif
|
||||
|
||||
#if 1U >> -16 != 0x10000
|
||||
#error 1U >> -16 != 0x10000
|
||||
#endif
|
||||
|
||||
#if -1U << 32 != 0
|
||||
#error -1U << 32 != 0
|
||||
#endif
|
||||
|
||||
#if -1U << -32 != 0
|
||||
#error -1U << -32 != 0
|
||||
#endif
|
||||
|
||||
#if -1U >> 32 != 0
|
||||
#error -1U >> 32 != 0
|
||||
#endif
|
||||
|
||||
#if -1U >> -32 != 0
|
||||
#error -1U >> -32 != 0
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user