diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2018-09-11 17:35:08 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-11 17:35:08 (GMT) |
commit | ed74a258aab2d5ca56a311acffdc7a46ca8ce2a1 (patch) | |
tree | aa6ad6f6f31d3a74080102adb3bb9965099ec09e | |
parent | 2173bb818c6c726d831b106ed0d3fad7825905dc (diff) | |
download | cpython-ed74a258aab2d5ca56a311acffdc7a46ca8ce2a1.zip cpython-ed74a258aab2d5ca56a311acffdc7a46ca8ce2a1.tar.gz cpython-ed74a258aab2d5ca56a311acffdc7a46ca8ce2a1.tar.bz2 |
Fix Tools/gdb/libpython.py
Backport https://github.com/python/cpython/commit/11659d00b9185c8f02ea6b642fa475a80e21f1a9
into this change instead of leaving it a separate followup change.
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst | 3 | ||||
-rw-r--r-- | Objects/dict-common.h | 11 | ||||
-rw-r--r-- | Objects/dictobject.c | 27 | ||||
-rwxr-xr-x | Tools/gdb/libpython.py | 2 |
4 files changed, 18 insertions, 25 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst new file mode 100644 index 0000000..40b51b9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst @@ -0,0 +1,3 @@ +Fixed clang ubsan (undefined behavior sanitizer) warnings in dictobject.c by +adjusting how the internal struct _dictkeysobject shared keys structure is +declared. diff --git a/Objects/dict-common.h b/Objects/dict-common.h index ce9edab..d3ae07b 100644 --- a/Objects/dict-common.h +++ b/Objects/dict-common.h @@ -59,15 +59,8 @@ struct _dictkeysobject { - 4 bytes if dk_size <= 0xffffffff (int32_t*) - 8 bytes otherwise (int64_t*) - Dynamically sized, 8 is minimum. */ - union { - int8_t as_1[8]; - int16_t as_2[4]; - int32_t as_4[2]; -#if SIZEOF_VOID_P > 4 - int64_t as_8[1]; -#endif - } dk_indices; + Dynamically sized, SIZEOF_VOID_P is minimum. */ + char dk_indices[]; /* char is required to avoid strict aliasing. */ /* "PyDictKeyEntry dk_entries[dk_usable];" array follows: see the DK_ENTRIES() macro */ diff --git a/Objects/dictobject.c b/Objects/dictobject.c index ddd0582..0768d11 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -300,7 +300,7 @@ PyDict_Fini(void) 2 : sizeof(int32_t)) #endif #define DK_ENTRIES(dk) \ - ((PyDictKeyEntry*)(&(dk)->dk_indices.as_1[DK_SIZE(dk) * DK_IXSIZE(dk)])) + ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)])) #define DK_DEBUG_INCREF _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA #define DK_DEBUG_DECREF _Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA @@ -318,21 +318,21 @@ dk_get_index(PyDictKeysObject *keys, Py_ssize_t i) Py_ssize_t ix; if (s <= 0xff) { - int8_t *indices = keys->dk_indices.as_1; + int8_t *indices = (int8_t*)(keys->dk_indices); ix = indices[i]; } else if (s <= 0xffff) { - int16_t *indices = keys->dk_indices.as_2; + int16_t *indices = (int16_t*)(keys->dk_indices); ix = indices[i]; } #if SIZEOF_VOID_P > 4 else if (s > 0xffffffff) { - int64_t *indices = keys->dk_indices.as_8; + int64_t *indices = (int64_t*)(keys->dk_indices); ix = indices[i]; } #endif else { - int32_t *indices = keys->dk_indices.as_4; + int32_t *indices = (int32_t*)(keys->dk_indices); ix = indices[i]; } assert(ix >= DKIX_DUMMY); @@ -348,23 +348,23 @@ dk_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) assert(ix >= DKIX_DUMMY); if (s <= 0xff) { - int8_t *indices = keys->dk_indices.as_1; + int8_t *indices = (int8_t*)(keys->dk_indices); assert(ix <= 0x7f); indices[i] = (char)ix; } else if (s <= 0xffff) { - int16_t *indices = keys->dk_indices.as_2; + int16_t *indices = (int16_t*)(keys->dk_indices); assert(ix <= 0x7fff); indices[i] = (int16_t)ix; } #if SIZEOF_VOID_P > 4 else if (s > 0xffffffff) { - int64_t *indices = keys->dk_indices.as_8; + int64_t *indices = (int64_t*)(keys->dk_indices); indices[i] = ix; } #endif else { - int32_t *indices = keys->dk_indices.as_4; + int32_t *indices = (int32_t*)(keys->dk_indices); assert(ix <= 0x7fffffff); indices[i] = (int32_t)ix; } @@ -424,8 +424,8 @@ static PyDictKeysObject empty_keys_struct = { lookdict_split, /* dk_lookup */ 0, /* dk_usable (immutable) */ 0, /* dk_nentries */ - .dk_indices = { .as_1 = {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, - DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}}, + {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, + DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */ }; static PyObject *empty_values[1] = { NULL }; @@ -533,7 +533,6 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size) } else { dk = PyObject_MALLOC(sizeof(PyDictKeysObject) - - Py_MEMBER_SIZE(PyDictKeysObject, dk_indices) + es * size + sizeof(PyDictKeyEntry) * usable); if (dk == NULL) { @@ -546,7 +545,7 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size) dk->dk_usable = usable; dk->dk_lookup = lookdict_unicode_nodummy; dk->dk_nentries = 0; - memset(&dk->dk_indices.as_1[0], 0xff, es * size); + memset(&dk->dk_indices[0], 0xff, es * size); memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable); return dk; } @@ -3086,7 +3085,6 @@ _PyDict_SizeOf(PyDictObject *mp) in the type object. */ if (mp->ma_keys->dk_refcnt == 1) res += (sizeof(PyDictKeysObject) - - Py_MEMBER_SIZE(PyDictKeysObject, dk_indices) + DK_IXSIZE(mp->ma_keys) * size + sizeof(PyDictKeyEntry) * usable); return res; @@ -3096,7 +3094,6 @@ Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys) { return (sizeof(PyDictKeysObject) - - Py_MEMBER_SIZE(PyDictKeysObject, dk_indices) + DK_IXSIZE(keys) * DK_SIZE(keys) + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry)); } diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 6d7a942..6d3d52f 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -736,7 +736,7 @@ class PyDictObjectPtr(PyObjectPtr): else: offset = 8 * dk_size - ent_addr = keys['dk_indices']['as_1'].address + ent_addr = keys['dk_indices'].address ent_addr = ent_addr.cast(_type_unsigned_char_ptr()) + offset ent_ptr_t = gdb.lookup_type('PyDictKeyEntry').pointer() ent_addr = ent_addr.cast(ent_ptr_t) |