bpo-42262: Py_NewRef() casts its argument to PyObject* (GH-23626)

Write also unit tests on Py_NewRef() and Py_XNewRef().
This commit is contained in:
Victor Stinner 2020-12-03 14:01:10 +01:00 committed by GitHub
parent 7e5e13d113
commit 8b6c4a921a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 5 deletions

View File

@ -426,7 +426,6 @@ static inline void _Py_INCREF(PyObject *op)
#endif #endif
op->ob_refcnt++; op->ob_refcnt++;
} }
#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op)) #define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op))
static inline void _Py_DECREF( static inline void _Py_DECREF(
@ -449,7 +448,6 @@ static inline void _Py_DECREF(
_Py_Dealloc(op); _Py_Dealloc(op);
} }
} }
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
# define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) # define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
#else #else
@ -548,8 +546,8 @@ static inline PyObject* _Py_XNewRef(PyObject *obj)
// Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI. // Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI.
// Names overriden with macros by static inline functions for best // Names overriden with macros by static inline functions for best
// performances. // performances.
#define Py_NewRef(obj) _Py_NewRef(obj) #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
#define Py_XNewRef(obj) _Py_XNewRef(obj) #define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
/* /*

View File

@ -5614,7 +5614,7 @@ static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
static PyObject* static PyObject*
test_set_type_size(PyObject* self, PyObject* ignored) test_set_type_size(PyObject *self, PyObject *Py_UNUSED(ignored))
{ {
PyObject *obj = PyList_New(0); PyObject *obj = PyList_New(0);
if (obj == NULL) { if (obj == NULL) {
@ -5636,6 +5636,35 @@ test_set_type_size(PyObject* self, PyObject* ignored)
} }
// Test Py_NewRef() and Py_XNewRef() functions
static PyObject*
test_refcount(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyObject *obj = PyList_New(0);
if (obj == NULL) {
return NULL;
}
assert(Py_REFCNT(obj) == 1);
// Test Py_NewRef()
PyObject *ref = Py_NewRef(obj);
assert(ref == obj);
assert(Py_REFCNT(obj) == 2);
Py_DECREF(ref);
// Test Py_XNewRef()
PyObject *xref = Py_XNewRef(obj);
assert(xref == obj);
assert(Py_REFCNT(obj) == 2);
Py_DECREF(xref);
assert(Py_XNewRef(NULL) == NULL);
Py_DECREF(obj);
Py_RETURN_NONE;
}
static PyMethodDef TestMethods[] = { static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS}, {"raise_exception", raise_exception, METH_VARARGS},
{"raise_memoryerror", raise_memoryerror, METH_NOARGS}, {"raise_memoryerror", raise_memoryerror, METH_NOARGS},
@ -5908,6 +5937,7 @@ static PyMethodDef TestMethods[] = {
{"pynumber_tobase", pynumber_tobase, METH_VARARGS}, {"pynumber_tobase", pynumber_tobase, METH_VARARGS},
{"without_gc", without_gc, METH_O}, {"without_gc", without_gc, METH_O},
{"test_set_type_size", test_set_type_size, METH_NOARGS}, {"test_set_type_size", test_set_type_size, METH_NOARGS},
{"test_refcount", test_refcount, METH_NOARGS},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };