mirror of
https://github.com/micropython/micropython.git
synced 2025-08-20 09:30:37 +02:00
py/obj: Add static safety checks to mp_obj_is_type().
Commitd96cfd13e3
introduced a regression by breaking existing users of mp_obj_is_type(.., &mp_obj_bool). This function (and associated helpers like mp_obj_is_int()) have some specific nuances, and mistakes like this one can happen again. This commit adds mp_obj_is_exact_type() which behaves like the the old mp_obj_is_type(). The new mp_obj_is_type() has the same prototype but it attempts to statically assert that it's not called with types which should be checked using mp_obj_is_type(). If called with any of these types: int, str, bool, NoneType - it will cause a compilation error. Additional checked types (e.g function types) can be added in the future. Existing users of mp_obj_is_type() with the now "invalid" types, were translated to use mp_obj_is_exact_type(). The use of MP_STATIC_ASSERT() is not bulletproof - usually GCC (and other compilers) can't statically check conditions that are only known during link-time (like variables' addresses comparison). However, in this case, GCC is able to statically detect these conditions, probably because it's the exact same object - `&mp_type_int == &mp_type_int` is detected. Misuses of this function with runtime-chosen types (e.g: `mp_obj_type_t *x = ...; mp_obj_is_type(..., x);` won't be detected. MSC is unable to detect this, so we use MP_STATIC_ASSERT_NOT_MSC(). Compiling with this commit and without the fix ford96cfd13e3
shows that it detects the problem. Signed-off-by: Yonatan Goldschmidt <yon.goldschmidt@gmail.com>
This commit is contained in:
committed by
Damien George
parent
6670281472
commit
2a6ba47110
@@ -91,7 +91,7 @@ mp_obj_int_t *mp_obj_int_new_mpz(void) {
|
||||
// This particular routine should only be called for the mpz representation of the int.
|
||||
char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
|
||||
int base, const char *prefix, char base_char, char comma) {
|
||||
assert(mp_obj_is_type(self_in, &mp_type_int));
|
||||
assert(mp_obj_is_exact_type(self_in, &mp_type_int));
|
||||
const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
size_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma);
|
||||
@@ -113,7 +113,7 @@ mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf
|
||||
}
|
||||
|
||||
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) {
|
||||
assert(mp_obj_is_type(self_in, &mp_type_int));
|
||||
assert(mp_obj_is_exact_type(self_in, &mp_type_int));
|
||||
mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mpz_as_bytes(&self->mpz, big_endian, len, buf);
|
||||
}
|
||||
@@ -181,7 +181,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
|
||||
mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(lhs_in));
|
||||
zlhs = &z_int;
|
||||
} else {
|
||||
assert(mp_obj_is_type(lhs_in, &mp_type_int));
|
||||
assert(mp_obj_is_exact_type(lhs_in, &mp_type_int));
|
||||
zlhs = &((mp_obj_int_t *)MP_OBJ_TO_PTR(lhs_in))->mpz;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
|
||||
if (mp_obj_is_small_int(rhs_in)) {
|
||||
mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(rhs_in));
|
||||
zrhs = &z_int;
|
||||
} else if (mp_obj_is_type(rhs_in, &mp_type_int)) {
|
||||
} else if (mp_obj_is_exact_type(rhs_in, &mp_type_int)) {
|
||||
zrhs = &((mp_obj_int_t *)MP_OBJ_TO_PTR(rhs_in))->mpz;
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
} else if (mp_obj_is_float(rhs_in)) {
|
||||
@@ -447,7 +447,7 @@ mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) {
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
mp_float_t mp_obj_int_as_float_impl(mp_obj_t self_in) {
|
||||
assert(mp_obj_is_type(self_in, &mp_type_int));
|
||||
assert(mp_obj_is_exact_type(self_in, &mp_type_int));
|
||||
mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mpz_as_float(&self->mpz);
|
||||
}
|
||||
|
Reference in New Issue
Block a user