diff options
author | Yonatan Goldschmidt <yon.goldschmidt@gmail.com> | 2020-01-22 13:34:19 +0100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2022-07-18 11:17:46 +1000 |
commit | 2a6ba47110be88ff1e1f5abd1bd76c353447884c (patch) | |
tree | bfcbdca7337b6e47d1315dbf14cb339833d0e944 /py/map.c | |
parent | 6670281472aa3c931b08e623488a02c335aeda20 (diff) |
py/obj: Add static safety checks to mp_obj_is_type().
Commit d96cfd13e3a464862c 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 for d96cfd13e3a464862c shows
that it detects the problem.
Signed-off-by: Yonatan Goldschmidt <yon.goldschmidt@gmail.com>
Diffstat (limited to 'py/map.c')
-rw-r--r-- | py/map.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -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, |