diff options
Diffstat (limited to 'Objects/tupleobject.c')
-rw-r--r-- | Objects/tupleobject.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 3e3aea4..e64b93b 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -6,6 +6,7 @@ #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_pyerrors.h" // _Py_FatalRefcountError() /*[clinic input] class tuple "PyTupleObject *" "&PyTuple_Type" @@ -287,6 +288,17 @@ tupledealloc(PyTupleObject *op) } #endif } +#if defined(Py_DEBUG) && PyTuple_MAXSAVESIZE > 0 + else { + assert(len == 0); + struct _Py_tuple_state *state = get_tuple_state(); + // The empty tuple singleton must only be deallocated by + // _PyTuple_Fini(): not before, not after + if (op == state->free_list[0] && state->numfree[0] != 0) { + _Py_FatalRefcountError("deallocating the empty tuple singleton"); + } + } +#endif Py_TYPE(op)->tp_free((PyObject *)op); #if PyTuple_MAXSAVESIZE > 0 @@ -1048,11 +1060,16 @@ _PyTuple_Fini(PyInterpreterState *interp) struct _Py_tuple_state *state = &interp->tuple; // The empty tuple singleton must not be tracked by the GC assert(!_PyObject_GC_IS_TRACKED(state->free_list[0])); + +#ifdef Py_DEBUG + state->numfree[0] = 0; +#endif Py_CLEAR(state->free_list[0]); - _PyTuple_ClearFreeList(interp); #ifdef Py_DEBUG state->numfree[0] = -1; #endif + + _PyTuple_ClearFreeList(interp); #endif } |