mirror of
https://github.com/micropython/micropython.git
synced 2025-08-21 01:50:39 +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
2
py/map.c
2
py/map.c
@@ -174,7 +174,7 @@ mp_map_elem_t *MICROPY_WRAP_MP_MAP_LOOKUP(mp_map_lookup)(mp_map_t * map, mp_obj_
|
||||
if (compare_only_ptrs) {
|
||||
if (mp_obj_is_qstr(index)) {
|
||||
// Index is a qstr, so can just do ptr comparison.
|
||||
} else if (mp_obj_is_type(index, &mp_type_str)) {
|
||||
} else if (mp_obj_is_exact_type(index, &mp_type_str)) {
|
||||
// Index is a non-interned string.
|
||||
// We can either intern the string, or force a full equality comparison.
|
||||
// We chose the latter, since interning costs time and potentially RAM,
|
||||
|
Reference in New Issue
Block a user