diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2019-12-28 20:17:49 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2019-12-28 20:17:49 +0100 |
commit | 20787f28fae6c0c828940a25e580b56a1f594efd (patch) | |
tree | 5c115c259faae5ceab810427173a6054c8188b3c | |
parent | 14fd58bbf44be7f9b72bc3b5d77dcbd86b988b03 (diff) | |
parent | ada8dbd865497ff4dd32a49d56a20cd74be498dc (diff) | |
download | cython-20787f28fae6c0c828940a25e580b56a1f594efd.tar.gz |
Merge branch '0.29.x'
-rw-r--r-- | CHANGES.rst | 10 | ||||
-rw-r--r-- | Cython/Compiler/ExprNodes.py | 25 | ||||
-rw-r--r-- | Cython/Compiler/Nodes.py | 18 | ||||
-rw-r--r-- | tests/run/py3k_super.pyx | 20 |
4 files changed, 55 insertions, 18 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index f23899a32..6186ae744 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -166,6 +166,16 @@ Other changes * Support for Python 2.6 was removed. +0.29.15 (20??-??-??) +==================== + +* Double reference free in ``__class__`` cell handling for ``super()`` calls. + (Github issue #3246) + +* Deprecated import failed in Python 3.9. + (Github issue #3266) + + 0.29.14 (2019-11-01) ==================== diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 0bc099ca3..743f2ee83 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -9103,21 +9103,20 @@ class ClassCellInjectorNode(ExprNode): def analyse_expressions(self, env): return self - def generate_evaluation_code(self, code): - if self.is_active: - self.allocate_temp_result(code) - code.putln( - '%s = PyList_New(0); %s' % ( - self.result(), - code.error_goto_if_null(self.result(), self.pos))) - code.put_gotref(self.result()) + def generate_result_code(self, code): + assert self.is_active + code.putln( + '%s = PyList_New(0); %s' % ( + self.result(), + code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.result()) def generate_injection_code(self, code, classobj_cname): - if self.is_active: - code.globalstate.use_utility_code( - UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c")) - code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % ( - self.result(), classobj_cname)) + assert self.is_active + code.globalstate.use_utility_code( + UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c")) + code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % ( + self.result(), classobj_cname)) class ClassCellNode(ExprNode): diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index c75a9c362..19d245106 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -4818,12 +4818,22 @@ class PyClassDefNode(ClassDefNode): self.metaclass.generate_evaluation_code(code) self.dict.generate_evaluation_code(code) cenv.namespace_cname = cenv.class_obj_cname = self.dict.result() - self.class_cell.generate_evaluation_code(code) + + class_cell = self.class_cell + if class_cell is not None and not class_cell.is_active: + class_cell = None + + if class_cell is not None: + class_cell.generate_evaluation_code(code) self.body.generate_execution_code(code) self.class_result.generate_evaluation_code(code) - self.class_cell.generate_injection_code( - code, self.class_result.result()) - self.class_cell.generate_disposal_code(code) + if class_cell is not None: + class_cell.generate_injection_code( + code, self.class_result.result()) + if class_cell is not None: + class_cell.generate_disposal_code(code) + class_cell.free_temps(code) + cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result() self.target.generate_assignment_code(self.class_result, code) self.dict.generate_disposal_code(code) diff --git a/tests/run/py3k_super.pyx b/tests/run/py3k_super.pyx index 97ff3de14..2968b99b2 100644 --- a/tests/run/py3k_super.pyx +++ b/tests/run/py3k_super.pyx @@ -1,5 +1,5 @@ # mode: run -# tag: py3k_super +# tag: py3k_super, gh3246 class A(object): def method(self): @@ -89,3 +89,21 @@ cdef class CClassSub(CClassBase): # return super().method_cp() # cdef method_c(self): # return super().method_c() + + +def freeing_class_cell_temp_gh3246(): + # https://github.com/cython/cython/issues/3246 + """ + >>> abc = freeing_class_cell_temp_gh3246() + >>> abc().a + 1 + """ + class SimpleBase(object): + def __init__(self): + self.a = 1 + + class ABC(SimpleBase): + def __init__(self): + super().__init__() + + return ABC |