bpo-35059: Add _PyObject_CAST() macro (GH-10645)

Add _PyObject_CAST() and _PyVarObject_CAST() macros to cast argument
to PyObject* and PyVarObject* properly.
This commit is contained in:
Victor Stinner 2018-11-22 02:57:29 +01:00 committed by GitHub
parent 271753a27a
commit 2ff8fb7639
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 23 deletions

View file

@ -42,7 +42,7 @@ static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno,
} }
#define _PyObject_GC_TRACK(op) \ #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. /* 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) \ #define _PyObject_GC_UNTRACK(op) \
_PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, (PyObject *)(op)) _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op))
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -112,14 +112,20 @@ typedef struct _object {
struct _typeobject *ob_type; struct _typeobject *ob_type;
} PyObject; } PyObject;
/* Cast argument to PyObject* type. */
#define _PyObject_CAST(op) ((PyObject*)(op))
typedef struct { typedef struct {
PyObject ob_base; PyObject ob_base;
Py_ssize_t ob_size; /* Number of items in variable part */ Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject; } PyVarObject;
#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) /* Cast argument to PyVarObject* type. */
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define _PyVarObject_CAST(op) ((PyVarObject*)(op))
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
#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 #ifndef Py_LIMITED_API
/********************* String Literals ****************************************/ /********************* String Literals ****************************************/
@ -814,7 +820,7 @@ static inline void _Py_INCREF(PyObject *op)
op->ob_refcnt++; 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, static inline void _Py_DECREF(const char *filename, int lineno,
PyObject *op) 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 /* 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) \ #define Py_CLEAR(op) \
do { \ do { \
PyObject *_py_tmp = (PyObject *)(op); \ PyObject *_py_tmp = _PyObject_CAST(op); \
if (_py_tmp != NULL) { \ if (_py_tmp != NULL) { \
(op) = NULL; \ (op) = NULL; \
Py_DECREF(_py_tmp); \ 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) 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 #ifndef Py_LIMITED_API
/* Safely decref `op` and set `op` to `op2`. /* Safely decref `op` and set `op` to `op2`.
@ -919,14 +925,14 @@ static inline void _Py_XDECREF(PyObject *op)
#define Py_SETREF(op, op2) \ #define Py_SETREF(op, op2) \
do { \ do { \
PyObject *_py_tmp = (PyObject *)(op); \ PyObject *_py_tmp = _PyObject_CAST(op); \
(op) = (op2); \ (op) = (op2); \
Py_DECREF(_py_tmp); \ Py_DECREF(_py_tmp); \
} while (0) } while (0)
#define Py_XSETREF(op, op2) \ #define Py_XSETREF(op, op2) \
do { \ do { \
PyObject *_py_tmp = (PyObject *)(op); \ PyObject *_py_tmp = _PyObject_CAST(op); \
(op) = (op2); \ (op) = (op2); \
Py_XDECREF(_py_tmp); \ Py_XDECREF(_py_tmp); \
} while (0) } while (0)
@ -1122,7 +1128,7 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void);
_PyTrash_thread_destroy_chain(); \ _PyTrash_thread_destroy_chain(); \
} \ } \
else \ else \
_PyTrash_thread_deposit_object((PyObject*)op); \ _PyTrash_thread_deposit_object(_PyObject_CAST(op)); \
} while (0); } while (0);
#ifndef Py_LIMITED_API #ifndef Py_LIMITED_API

View file

@ -258,7 +258,7 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);
PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t);
#define PyObject_GC_Resize(type, op, n) \ #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 #ifndef Py_LIMITED_API
@ -356,7 +356,7 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *);
#define Py_VISIT(op) \ #define Py_VISIT(op) \
do { \ do { \
if (op) { \ if (op) { \
int vret = visit((PyObject *)(op), arg); \ int vret = visit(_PyObject_CAST(op), arg); \
if (vret) \ if (vret) \
return vret; \ return vret; \
} \ } \

View file

@ -27,13 +27,13 @@ PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item);
PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key);
/* wrappers around PyDict* functions */ /* 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) \ #define PyODict_GetItemWithError(od, key) \
PyDict_GetItemWithError((PyObject *)od, key) PyDict_GetItemWithError(_PyObject_CAST(od), key)
#define PyODict_Contains(od, key) PyDict_Contains((PyObject *)od, key) #define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key)
#define PyODict_Size(od) PyDict_Size((PyObject *)od) #define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od))
#define PyODict_GetItemString(od, key) \ #define PyODict_GetItemString(od, key) \
PyDict_GetItemString((PyObject *)od, key) PyDict_GetItemString(_PyObject_CAST(od), key)
#endif #endif

View file

@ -380,7 +380,7 @@ PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type;
(assert(PyUnicode_Check(op)), \ (assert(PyUnicode_Check(op)), \
(((PyASCIIObject *)(op))->wstr) ? \ (((PyASCIIObject *)(op))->wstr) ? \
PyUnicode_WSTR_LENGTH(op) : \ PyUnicode_WSTR_LENGTH(op) : \
((void)PyUnicode_AsUnicode((PyObject *)(op)), \ ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
assert(((PyASCIIObject *)(op))->wstr), \ assert(((PyASCIIObject *)(op))->wstr), \
PyUnicode_WSTR_LENGTH(op))) PyUnicode_WSTR_LENGTH(op)))
/* Py_DEPRECATED(3.3) */ /* Py_DEPRECATED(3.3) */
@ -397,7 +397,7 @@ PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type;
#define PyUnicode_AS_UNICODE(op) \ #define PyUnicode_AS_UNICODE(op) \
(assert(PyUnicode_Check(op)), \ (assert(PyUnicode_Check(op)), \
(((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \
PyUnicode_AsUnicode((PyObject *)(op))) PyUnicode_AsUnicode(_PyObject_CAST(op)))
/* Py_DEPRECATED(3.3) */ /* Py_DEPRECATED(3.3) */
#define PyUnicode_AS_DATA(op) \ #define PyUnicode_AS_DATA(op) \
@ -549,7 +549,7 @@ enum PyUnicode_Kind {
#define PyUnicode_READY(op) \ #define PyUnicode_READY(op) \
(assert(PyUnicode_Check(op)), \ (assert(PyUnicode_Check(op)), \
(PyUnicode_IS_READY(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 /* Return a maximum character value which is suitable for creating another
string based on op. This is always an approximation but more efficient string based on op. This is always an approximation but more efficient