mirror of
https://github.com/python/cpython.git
synced 2025-10-26 16:27:06 +00:00
Revert "gh-98724: Fix Py_CLEAR() macro side effects" (#99737)
Revert "gh-98724: Fix Py_CLEAR() macro side effects (#99100)"
This reverts commit c03e05c2e7.
This commit is contained in:
parent
0da728387c
commit
3a803bcaac
5 changed files with 29 additions and 172 deletions
|
|
@ -305,41 +305,37 @@ _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *,
|
|||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
|
||||
|
||||
/* Safely decref `dst` and set `dst` to `src`.
|
||||
/* Safely decref `op` and set `op` to `op2`.
|
||||
*
|
||||
* As in case of Py_CLEAR "the obvious" code can be deadly:
|
||||
*
|
||||
* Py_DECREF(dst);
|
||||
* dst = src;
|
||||
* Py_DECREF(op);
|
||||
* op = op2;
|
||||
*
|
||||
* The safe way is:
|
||||
*
|
||||
* Py_SETREF(dst, src);
|
||||
* Py_SETREF(op, op2);
|
||||
*
|
||||
* That arranges to set `dst` to `src` _before_ decref'ing, so that any code
|
||||
* triggered as a side-effect of `dst` getting torn down no longer believes
|
||||
* `dst` points to a valid object.
|
||||
* That arranges to set `op` to `op2` _before_ decref'ing, so that any code
|
||||
* triggered as a side-effect of `op` getting torn down no longer believes
|
||||
* `op` points to a valid object.
|
||||
*
|
||||
* gh-98724: Use the _tmp_dst_ptr variable to evaluate the 'dst' macro argument
|
||||
* exactly once, to prevent the duplication of side effects in this macro.
|
||||
* Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of
|
||||
* Py_DECREF.
|
||||
*/
|
||||
#define Py_SETREF(dst, src) \
|
||||
do { \
|
||||
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
|
||||
PyObject *_tmp_dst = (*_tmp_dst_ptr); \
|
||||
*_tmp_dst_ptr = _PyObject_CAST(src); \
|
||||
Py_DECREF(_tmp_dst); \
|
||||
|
||||
#define Py_SETREF(op, op2) \
|
||||
do { \
|
||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
||||
(op) = (op2); \
|
||||
Py_DECREF(_py_tmp); \
|
||||
} while (0)
|
||||
|
||||
/* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of
|
||||
* Py_DECREF().
|
||||
*/
|
||||
#define Py_XSETREF(dst, src) \
|
||||
do { \
|
||||
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
|
||||
PyObject *_tmp_dst = (*_tmp_dst_ptr); \
|
||||
*_tmp_dst_ptr = _PyObject_CAST(src); \
|
||||
Py_XDECREF(_tmp_dst); \
|
||||
#define Py_XSETREF(op, op2) \
|
||||
do { \
|
||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
||||
(op) = (op2); \
|
||||
Py_XDECREF(_py_tmp); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -598,21 +598,16 @@ 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_ptr = _Py_CAST(PyObject**, &(op)); \
|
||||
if (*_py_tmp_ptr != NULL) { \
|
||||
PyObject* _py_tmp = (*_py_tmp_ptr); \
|
||||
*_py_tmp_ptr = NULL; \
|
||||
Py_DECREF(_py_tmp); \
|
||||
} \
|
||||
#define Py_CLEAR(op) \
|
||||
do { \
|
||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
||||
if (_py_tmp != NULL) { \
|
||||
(op) = 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