mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 00:29:31 +00:00
fix for #1941, taken from 22d435b689
This commit is contained in:
parent
60f56c43c7
commit
1764b7aca9
@ -169,27 +169,21 @@ void ShiftExpr (struct ExprDesc* Expr)
|
||||
}
|
||||
}
|
||||
|
||||
/* If the shift count is zero, nothing happens. If the left hand
|
||||
** side is a constant, the result is constant.
|
||||
*/
|
||||
if (Expr2.IVal == 0 || lconst) {
|
||||
|
||||
/* Set the type */
|
||||
/* If the left hand side is a constant, the result is constant */
|
||||
if (lconst) {
|
||||
/* Set the result type */
|
||||
Expr->Type = ResultType;
|
||||
|
||||
if (lconst) {
|
||||
|
||||
/* Evaluate the result */
|
||||
switch (Tok) {
|
||||
case TOK_SHL: Expr->IVal <<= Expr2.IVal; break;
|
||||
case TOK_SHR: Expr->IVal >>= Expr2.IVal; break;
|
||||
default: /* Shutup gcc */ break;
|
||||
}
|
||||
|
||||
/* Limit the calculated value to the range of its type */
|
||||
LimitExprValue (Expr, 1);
|
||||
/* Evaluate the result */
|
||||
switch (Tok) {
|
||||
case TOK_SHL: Expr->IVal <<= Expr2.IVal; break;
|
||||
case TOK_SHR: Expr->IVal >>= Expr2.IVal; break;
|
||||
default: /* Shutup gcc */ break;
|
||||
}
|
||||
|
||||
/* Limit the calculated value to the range of its type */
|
||||
LimitExprValue (Expr, 1);
|
||||
|
||||
/* Result is already got, remove the generated code */
|
||||
RemoveCode (&Mark1);
|
||||
|
||||
@ -197,6 +191,15 @@ void ShiftExpr (struct ExprDesc* Expr)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the shift count is zero, nothing happens */
|
||||
if (Expr2.IVal == 0) {
|
||||
/* Result is already got, remove the pushing code */
|
||||
RemoveCode (&Mark2);
|
||||
|
||||
/* Be sure to mark the value as in the primary */
|
||||
goto MakeRVal;
|
||||
}
|
||||
|
||||
/* If we're shifting an integer or unsigned to the right, the lhs
|
||||
** has a quasi-const address, and the shift count is larger than 8,
|
||||
** we can load just the high byte as a char with the correct
|
||||
|
28
test/val/bug1941-shift-by-zero.c
Normal file
28
test/val/bug1941-shift-by-zero.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* Bug 1941 - Bitwise shift char types by 0 count results in out-of-range access */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t foo = 42U; /* "Low byte" */
|
||||
uint8_t goo = 1U; /* "High byte" - you need it to reproduce the issue */
|
||||
int16_t bar = 256; /* ...or just do it with this */
|
||||
|
||||
_Static_assert (sizeof (foo >> 0) == sizeof (int), "Shift result should be int-promoted");
|
||||
_Static_assert (sizeof ((int8_t)bar << 0) == sizeof (int), "Shift result should be int-promoted");
|
||||
|
||||
unsigned failures;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (foo >> 0 != foo) {
|
||||
++failures;
|
||||
printf("foo failed\n");
|
||||
}
|
||||
|
||||
if ((int8_t)bar << 0 != (int8_t)bar) {
|
||||
++failures;
|
||||
printf("bar failed\n");
|
||||
}
|
||||
|
||||
return failures;
|
||||
}
|
Loading…
Reference in New Issue
Block a user