summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index acbe3fa..82faa79 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1231,14 +1231,22 @@ subtype_dealloc(PyObject *self)
/* Extract the type again; tp_del may have changed it */
type = Py_TYPE(self);
+ // Don't read type memory after calling basedealloc() since basedealloc()
+ // can deallocate the type and free its memory.
+ int type_needs_decref = (type->tp_flags & Py_TPFLAGS_HEAPTYPE
+ && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE));
+
/* Call the base tp_dealloc() */
assert(basedealloc);
basedealloc(self);
- /* Only decref if the base type is not already a heap allocated type.
- Otherwise, basedealloc should have decref'd it already */
- if (type->tp_flags & Py_TPFLAGS_HEAPTYPE && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ /* Can't reference self beyond this point. It's possible tp_del switched
+ our type from a HEAPTYPE to a non-HEAPTYPE, so be careful about
+ reference counting. Only decref if the base type is not already a heap
+ allocated type. Otherwise, basedealloc should have decref'd it already */
+ if (type_needs_decref) {
Py_DECREF(type);
+ }
/* Done */
return;