From 2ff8fb7639a86757c00a7cbbe7da418fffec3870 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 22 Nov 2018 02:57:29 +0100 Subject: [PATCH] bpo-35059: Add _PyObject_CAST() macro (GH-10645) Add _PyObject_CAST() and _PyVarObject_CAST() macros to cast argument to PyObject* and PyVarObject* properly. --- Include/internal/pycore_object.h | 4 ++-- Include/object.h | 28 +++++++++++++++++----------- Include/objimpl.h | 4 ++-- Include/odictobject.h | 10 +++++----- Include/unicodeobject.h | 6 +++--- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 347ab68801..a88b626332 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -42,7 +42,7 @@ static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, } #define _PyObject_GC_TRACK(op) \ - _PyObject_GC_TRACK_impl(__FILE__, __LINE__, (PyObject *)(op)) + _PyObject_GC_TRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) /* Tell the GC to stop tracking this object. * @@ -70,7 +70,7 @@ static inline void _PyObject_GC_UNTRACK_impl(const char *filename, int lineno, } #define _PyObject_GC_UNTRACK(op) \ - _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, (PyObject *)(op)) + _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) #ifdef __cplusplus } diff --git a/Include/object.h b/Include/object.h index 5947b79055..cdcdca85c6 100644 --- a/Include/object.h +++ b/Include/object.h @@ -112,14 +112,20 @@ typedef struct _object { struct _typeobject *ob_type; } PyObject; +/* Cast argument to PyObject* type. */ +#define _PyObject_CAST(op) ((PyObject*)(op)) + typedef struct { PyObject ob_base; Py_ssize_t ob_size; /* Number of items in variable part */ } PyVarObject; -#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) -#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) +/* Cast argument to PyVarObject* type. */ +#define _PyVarObject_CAST(op) ((PyVarObject*)(op)) + +#define Py_REFCNT(ob) (_PyObject_CAST(ob)->ob_refcnt) +#define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type) +#define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size) #ifndef Py_LIMITED_API /********************* String Literals ****************************************/ @@ -814,7 +820,7 @@ static inline void _Py_INCREF(PyObject *op) op->ob_refcnt++; } -#define Py_INCREF(op) _Py_INCREF((PyObject *)(op)) +#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op)) static inline void _Py_DECREF(const char *filename, int lineno, PyObject *op) @@ -832,7 +838,7 @@ static inline void _Py_DECREF(const char *filename, int lineno, } } -#define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, (PyObject *)(op)) +#define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear @@ -871,7 +877,7 @@ static inline void _Py_DECREF(const char *filename, int lineno, */ #define Py_CLEAR(op) \ do { \ - PyObject *_py_tmp = (PyObject *)(op); \ + PyObject *_py_tmp = _PyObject_CAST(op); \ if (_py_tmp != NULL) { \ (op) = NULL; \ Py_DECREF(_py_tmp); \ @@ -886,7 +892,7 @@ static inline void _Py_XINCREF(PyObject *op) } } -#define Py_XINCREF(op) _Py_XINCREF((PyObject *)(op)) +#define Py_XINCREF(op) _Py_XINCREF(_PyObject_CAST(op)) static inline void _Py_XDECREF(PyObject *op) { @@ -895,7 +901,7 @@ static inline void _Py_XDECREF(PyObject *op) } } -#define Py_XDECREF(op) _Py_XDECREF((PyObject *)(op)) +#define Py_XDECREF(op) _Py_XDECREF(_PyObject_CAST(op)) #ifndef Py_LIMITED_API /* Safely decref `op` and set `op` to `op2`. @@ -919,14 +925,14 @@ static inline void _Py_XDECREF(PyObject *op) #define Py_SETREF(op, op2) \ do { \ - PyObject *_py_tmp = (PyObject *)(op); \ + PyObject *_py_tmp = _PyObject_CAST(op); \ (op) = (op2); \ Py_DECREF(_py_tmp); \ } while (0) #define Py_XSETREF(op, op2) \ do { \ - PyObject *_py_tmp = (PyObject *)(op); \ + PyObject *_py_tmp = _PyObject_CAST(op); \ (op) = (op2); \ Py_XDECREF(_py_tmp); \ } while (0) @@ -1122,7 +1128,7 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void); _PyTrash_thread_destroy_chain(); \ } \ else \ - _PyTrash_thread_deposit_object((PyObject*)op); \ + _PyTrash_thread_deposit_object(_PyObject_CAST(op)); \ } while (0); #ifndef Py_LIMITED_API diff --git a/Include/objimpl.h b/Include/objimpl.h index c455d4bebb..1c50d8bd6c 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -258,7 +258,7 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void); PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); #define PyObject_GC_Resize(type, op, n) \ - ( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) ) + ( (type *) _PyObject_GC_Resize(_PyVarObject_CAST(op), (n)) ) #ifndef Py_LIMITED_API @@ -356,7 +356,7 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *); #define Py_VISIT(op) \ do { \ if (op) { \ - int vret = visit((PyObject *)(op), arg); \ + int vret = visit(_PyObject_CAST(op), arg); \ if (vret) \ return vret; \ } \ diff --git a/Include/odictobject.h b/Include/odictobject.h index 8378dc4bfa..35aff8a29a 100644 --- a/Include/odictobject.h +++ b/Include/odictobject.h @@ -27,13 +27,13 @@ PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); /* wrappers around PyDict* functions */ -#define PyODict_GetItem(od, key) PyDict_GetItem((PyObject *)od, key) +#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), key) #define PyODict_GetItemWithError(od, key) \ - PyDict_GetItemWithError((PyObject *)od, key) -#define PyODict_Contains(od, key) PyDict_Contains((PyObject *)od, key) -#define PyODict_Size(od) PyDict_Size((PyObject *)od) + PyDict_GetItemWithError(_PyObject_CAST(od), key) +#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key) +#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od)) #define PyODict_GetItemString(od, key) \ - PyDict_GetItemString((PyObject *)od, key) + PyDict_GetItemString(_PyObject_CAST(od), key) #endif diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 0274de6733..ffabf0e831 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -380,7 +380,7 @@ PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; (assert(PyUnicode_Check(op)), \ (((PyASCIIObject *)(op))->wstr) ? \ PyUnicode_WSTR_LENGTH(op) : \ - ((void)PyUnicode_AsUnicode((PyObject *)(op)), \ + ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\ assert(((PyASCIIObject *)(op))->wstr), \ PyUnicode_WSTR_LENGTH(op))) /* Py_DEPRECATED(3.3) */ @@ -397,7 +397,7 @@ PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; #define PyUnicode_AS_UNICODE(op) \ (assert(PyUnicode_Check(op)), \ (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ - PyUnicode_AsUnicode((PyObject *)(op))) + PyUnicode_AsUnicode(_PyObject_CAST(op))) /* Py_DEPRECATED(3.3) */ #define PyUnicode_AS_DATA(op) \ @@ -549,7 +549,7 @@ enum PyUnicode_Kind { #define PyUnicode_READY(op) \ (assert(PyUnicode_Check(op)), \ (PyUnicode_IS_READY(op) ? \ - 0 : _PyUnicode_Ready((PyObject *)(op)))) + 0 : _PyUnicode_Ready(_PyObject_CAST(op)))) /* Return a maximum character value which is suitable for creating another string based on op. This is always an approximation but more efficient -- 2.40.0