mirror of
https://github.com/W3SLAV/micropython.git
synced 2025-06-20 20:45:35 -04:00
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)) {
|
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_MORE)) {
|
||||||
// int >> int
|
// 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);
|
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 >> arg1);
|
||||||
} else {
|
} else {
|
||||||
// shouldn't happen
|
// 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"));
|
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count"));
|
||||||
} else {
|
} else {
|
||||||
// standard precision is enough for right-shift
|
// 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;
|
lhs_val >>= rhs_val;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -48,3 +48,17 @@ a -= 1
|
|||||||
print(a)
|
print(a)
|
||||||
# This would overflow
|
# This would overflow
|
||||||
#a -= 1
|
#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…
Reference in New Issue
Block a user