diff options
author | INADA Naoki <methane@users.noreply.github.com> | 2018-07-04 02:15:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-04 02:15:50 (GMT) |
commit | 3c452404ae178b742967589a0bb4a5ec768d76e0 (patch) | |
tree | 4f7f0c7ee425ee37c9c47ac3a1bb0d698d90ea23 /Objects | |
parent | d8cba5d16f1333fd625726fc72e66afbd45b8d00 (diff) | |
download | cpython-3c452404ae178b742967589a0bb4a5ec768d76e0.zip cpython-3c452404ae178b742967589a0bb4a5ec768d76e0.tar.gz cpython-3c452404ae178b742967589a0bb4a5ec768d76e0.tar.bz2 |
bpo-33418: Add tp_clear for function object (GH-8058)
Without tp_clear, GC can't break cyclic reference.
It will cause memory leak when cyclic reference is
created intentionally.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/funcobject.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 241685d..c2f79c0 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -523,23 +523,31 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, return (PyObject *)newfunc; } +static int +func_clear(PyFunctionObject *op) +{ + Py_CLEAR(op->func_code); + Py_CLEAR(op->func_globals); + Py_CLEAR(op->func_module); + Py_CLEAR(op->func_name); + Py_CLEAR(op->func_defaults); + Py_CLEAR(op->func_kwdefaults); + Py_CLEAR(op->func_doc); + Py_CLEAR(op->func_dict); + Py_CLEAR(op->func_closure); + Py_CLEAR(op->func_annotations); + Py_CLEAR(op->func_qualname); + return 0; +} + static void func_dealloc(PyFunctionObject *op) { _PyObject_GC_UNTRACK(op); - if (op->func_weakreflist != NULL) + if (op->func_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) op); - Py_DECREF(op->func_code); - Py_DECREF(op->func_globals); - Py_XDECREF(op->func_module); - Py_DECREF(op->func_name); - Py_XDECREF(op->func_defaults); - Py_XDECREF(op->func_kwdefaults); - Py_XDECREF(op->func_doc); - Py_XDECREF(op->func_dict); - Py_XDECREF(op->func_closure); - Py_XDECREF(op->func_annotations); - Py_XDECREF(op->func_qualname); + } + (void)func_clear(op); PyObject_GC_Del(op); } @@ -612,7 +620,7 @@ PyTypeObject PyFunction_Type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ func_new__doc__, /* tp_doc */ (traverseproc)func_traverse, /* tp_traverse */ - 0, /* tp_clear */ + (inquiry)func_clear, /* tp_clear */ 0, /* tp_richcompare */ offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ |