mirror of
https://github.com/python/cpython.git
synced 2025-11-02 19:12:55 +00:00
gh-98724: Fix Py_CLEAR() macro side effects (#99100)
The Py_CLEAR(), Py_SETREF() and Py_XSETREF() macros now only evaluate their argument once. If an argument has side effects, these side effects are no longer duplicated. Add test_py_clear() and test_py_setref() unit tests to _testcapi.
This commit is contained in:
parent
0124b5dd28
commit
c03e05c2e7
6 changed files with 175 additions and 29 deletions
|
|
@ -598,16 +598,21 @@ static inline void Py_DECREF(PyObject *op)
|
|||
* one of those can't cause problems -- but in part that relies on that
|
||||
* Python integers aren't currently weakly referencable. Best practice is
|
||||
* to use Py_CLEAR() even if you can't think of a reason for why you need to.
|
||||
*
|
||||
* gh-98724: Use the _py_tmp_ptr variable to evaluate the macro argument
|
||||
* exactly once, to prevent the duplication of side effects in this macro.
|
||||
*/
|
||||
#define Py_CLEAR(op) \
|
||||
do { \
|
||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
||||
if (_py_tmp != NULL) { \
|
||||
(op) = NULL; \
|
||||
Py_DECREF(_py_tmp); \
|
||||
} \
|
||||
#define Py_CLEAR(op) \
|
||||
do { \
|
||||
PyObject **_py_tmp_ptr = _Py_CAST(PyObject**, &(op)); \
|
||||
if (*_py_tmp_ptr != NULL) { \
|
||||
PyObject* _py_tmp = (*_py_tmp_ptr); \
|
||||
*_py_tmp_ptr = NULL; \
|
||||
Py_DECREF(_py_tmp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Function to use in case the object pointer can be NULL: */
|
||||
static inline void Py_XINCREF(PyObject *op)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue