diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2020-09-01 18:39:46 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-01 18:39:46 (GMT) |
commit | 9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0 (patch) | |
tree | bf8539814364c648b58965d3558014a23d6bcf4f /Objects/exceptions.c | |
parent | 6844b56176c41f0a0e25fcd4fef5463bcdbc7d7c (diff) | |
download | cpython-9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0.zip cpython-9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0.tar.gz cpython-9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0.tar.bz2 |
bpo-41654: Fix deallocator of MemoryError to account for subclasses (GH-22020)
When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError.
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r-- | Objects/exceptions.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 1195ba1..b08cbdd 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2286,8 +2286,11 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyBaseExceptionObject *self; - if (type != (PyTypeObject *) PyExc_MemoryError) + /* If this is a subclass of MemoryError, don't use the freelist + * and just return a fresh object */ + if (type != (PyTypeObject *) PyExc_MemoryError) { return BaseException_new(type, args, kwds); + } struct _Py_exc_state *state = get_exc_state(); if (state->memerrors_freelist == NULL) { @@ -2313,9 +2316,16 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void MemoryError_dealloc(PyBaseExceptionObject *self) { - _PyObject_GC_UNTRACK(self); BaseException_clear(self); + /* If this is a subclass of MemoryError, we don't need to + * do anything in the free-list*/ + if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) { + return Py_TYPE(self)->tp_free((PyObject *)self); + } + + _PyObject_GC_UNTRACK(self); + struct _Py_exc_state *state = get_exc_state(); if (state->memerrors_numfree >= MEMERRORS_SAVE) { Py_TYPE(self)->tp_free((PyObject *)self); |