py: Fix bug with right-shifting small ints by large amounts.
Undefined behavior in C, needs explicit check.
This commit is contained in:
parent
a58713a899
commit
039887a0ac
@ -233,6 +233,11 @@ STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_m
|
||||
}
|
||||
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_MORE)) {
|
||||
// int >> int
|
||||
if (arg1 >= BITS_PER_WORD) {
|
||||
// Shifting to big amounts is underfined behavior
|
||||
// in C and is CPU-dependent; propagate sign bit.
|
||||
arg1 = BITS_PER_WORD - 1;
|
||||
}
|
||||
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 >> arg1);
|
||||
} else {
|
||||
// shouldn't happen
|
||||
|
@ -337,6 +337,11 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count"));
|
||||
} else {
|
||||
// standard precision is enough for right-shift
|
||||
if (rhs_val >= BITS_PER_WORD) {
|
||||
// Shifting to big amounts is underfined behavior
|
||||
// in C and is CPU-dependent; propagate sign bit.
|
||||
rhs_val = BITS_PER_WORD - 1;
|
||||
}
|
||||
lhs_val >>= rhs_val;
|
||||
}
|
||||
break;
|
||||
|
@ -48,3 +48,17 @@ a -= 1
|
||||
print(a)
|
||||
# This would overflow
|
||||
#a -= 1
|
||||
|
||||
|
||||
# Shifts to big amounts are undefined behavior in C and is CPU-specific
|
||||
|
||||
# These are compile-time constexprs
|
||||
print(1 >> 32)
|
||||
print(1 >> 64)
|
||||
print(1 >> 128)
|
||||
|
||||
# These are runtime calcs
|
||||
a = 1
|
||||
print(a >> 32)
|
||||
print(a >> 64)
|
||||
print(a >> 128)
|
||||
|
Loading…
x
Reference in New Issue
Block a user