summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2020-09-01 20:40:48 (GMT)
committerGitHub <noreply@github.com>2020-09-01 20:40:48 (GMT)
commit77f4000ae0d43a2685face80e7f14d4aba053973 (patch)
tree1d49556219c04d147c74ccbe6eb3937b8d893363 /Objects
parent38e32872eb3cf0dc9dd8cef9b05e47ba03638d34 (diff)
downloadcpython-77f4000ae0d43a2685face80e7f14d4aba053973.zip
cpython-77f4000ae0d43a2685face80e7f14d4aba053973.tar.gz
cpython-77f4000ae0d43a2685face80e7f14d4aba053973.tar.bz2
[3.8] [3.9] bpo-41654: Fix deallocator of MemoryError to account for subclasses (GH-22020) (GH-22046)
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.. (cherry picked from commit 9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0) Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>. (cherry picked from commit 87e91ae2e5f81e096c32839f211c68a749a4435a) Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/exceptions.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 38723d9..9669838 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -2268,8 +2268,12 @@ 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);
+ }
+
if (memerrors_freelist == NULL)
return BaseException_new(type, args, kwds);
/* Fetch object from freelist and revive it */
@@ -2289,8 +2293,14 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void
MemoryError_dealloc(PyBaseExceptionObject *self)
{
- _PyObject_GC_UNTRACK(self);
BaseException_clear(self);
+
+ if (Py_TYPE(self) != PyExc_MemoryError) {
+ return Py_TYPE(self)->tp_free((PyObject *)self);
+ }
+
+ _PyObject_GC_UNTRACK(self);
+
if (memerrors_numfree >= MEMERRORS_SAVE)
Py_TYPE(self)->tp_free((PyObject *)self);
else {