mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									271753a27a
								
							
						
					
					
						commit
						2ff8fb7639
					
				
					 5 changed files with 29 additions and 23 deletions
				
			
		|  | @ -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 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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;                                            \ | ||||||
|         }                                                               \ |         }                                                               \ | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner