Commit d2aff824 authored by Stefan Behnel's avatar Stefan Behnel

fix crash by excluding heap types from the extension type freelists

parent 956f6502
......@@ -16,6 +16,9 @@ Features added
Bugs fixed
----------
* Crash when subtyping freelist enabled Cython extension types with
Python classes that use ``__slots__``.
* Memory leak in memory views when copying overlapping, contiguous slices.
* Format checking when requesting non-contiguous buffers from
......
......@@ -1172,7 +1172,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if is_final_type:
abstract_check = ''
else:
abstract_check = ' & ((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)'
abstract_check = ' & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)'
obj_struct = type.declaration_code("", deref=True)
code.putln("if (likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % (
freecount_name, obj_struct, abstract_check))
......
......@@ -12,6 +12,20 @@ cdef class ExtTypeNoGC:
>>> obj = ExtTypeNoGC()
>>> obj = ExtTypeNoGC()
>>> obj = ExtTypeNoGC()
>>> class PyClass(ExtTypeNoGC): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtTypeNoGC): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
......@@ -23,6 +37,20 @@ cdef class ExtSubTypeNoGC(ExtTypeNoGC):
>>> obj = ExtSubTypeNoGC()
>>> obj = ExtSubTypeNoGC()
>>> obj = ExtSubTypeNoGC()
>>> class PyClass(ExtSubTypeNoGC): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtSubTypeNoGC): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
cdef bytes x
......@@ -36,6 +64,20 @@ cdef class ExtTypeWithGC:
>>> obj = ExtTypeWithGC()
>>> obj = ExtTypeWithGC()
>>> obj = ExtTypeWithGC()
>>> class PyClass(ExtTypeWithGC): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtTypeWithGC): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
cdef attribute
......@@ -63,6 +105,20 @@ cdef class ExtSubType(ExtTypeWithGC):
>>> obj = ExtSubType()
>>> obj = ExtSubType()
>>> obj = ExtSubType()
>>> class PyClass(ExtSubType): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtSubType): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
......@@ -74,6 +130,20 @@ cdef class LargerExtSubType(ExtSubType):
>>> obj = LargerExtSubType()
>>> obj = LargerExtSubType()
>>> obj = LargerExtSubType()
>>> class PyClass(LargerExtSubType): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(LargerExtSubType): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
cdef attribute2
......@@ -90,6 +160,20 @@ cdef class ExtTypeWithCAttr:
>>> obj = ExtTypeWithCAttr()
>>> obj = ExtTypeWithCAttr()
>>> obj = ExtTypeWithCAttr()
>>> class PyClass(ExtTypeWithCAttr): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtTypeWithCAttr): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
cdef int cattr
......@@ -106,6 +190,18 @@ cdef class ExtSubTypeWithCAttr(ExtTypeWithCAttr):
>>> obj = ExtSubTypeWithCAttr()
>>> obj = ExtSubTypeWithCAttr()
>>> obj = ExtSubTypeWithCAttr()
>>> class PyClass(ExtSubTypeWithCAttr): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> class PyClass(ExtSubTypeWithCAttr): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
"""
......@@ -119,6 +215,20 @@ cdef class ExtTypeWithCAttrNoFreelist:
>>> obj = ExtTypeWithCAttrNoFreelist()
>>> obj = ExtTypeWithCAttrNoFreelist()
>>> obj = ExtTypeWithCAttrNoFreelist()
>>> class PyClass(ExtTypeWithCAttrNoFreelist): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtTypeWithCAttrNoFreelist): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
cdef int cattr
......@@ -148,6 +258,28 @@ cdef class ExtTypeWithCMethods:
>>> obj = ExtTypeWithCMethods()
>>> test_cmethods(obj)
(1, 2)
>>> class PyClass(ExtTypeWithCMethods): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> test_cmethods(obj)
(1, 2)
>>> obj = PyClass()
>>> test_cmethods(obj)
(1, 2)
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtTypeWithCMethods): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> test_cmethods(obj)
(1, 2)
>>> obj = PyClass()
>>> test_cmethods(obj)
(1, 2)
>>> obj = PyClass()
>>> del PyClass, obj
"""
cdef int cattr
......@@ -188,6 +320,20 @@ cdef class ExtSubTypeWithCMethods(ExtTypeWithCMethods):
>>> obj = ExtSubTypeWithCMethods()
>>> test_cmethods(obj)
(1, 2)
>>> class PyClass(ExtSubTypeWithCMethods): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtSubTypeWithCMethods): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
......@@ -232,6 +378,20 @@ cdef class ExtSubTypeWithMoreCMethods(ExtSubTypeWithCMethods):
>>> obj = ExtTypeWithCMethods()
>>> test_cmethods(obj)
(1, 2)
>>> class PyClass(ExtSubTypeWithMoreCMethods): a = 1
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtSubTypeWithMoreCMethods): __slots__ = ()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
def __cinit__(self):
assert self.cattr == 1
......@@ -270,6 +430,22 @@ cdef class ExtTypeWithRefCycle:
True
>>> first.attribute = obj
>>> del obj, first
>>> class PyClass(ExtTypeWithRefCycle): a = 1
>>> obj = PyClass()
>>> obj.attribute = obj
>>> obj.attribute = PyClass(obj)
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
>>> class PyClass(ExtTypeWithRefCycle): __slots__ = ()
>>> obj = PyClass()
>>> obj.attribute = obj
>>> obj.attribute = PyClass(obj)
>>> obj = PyClass()
>>> obj = PyClass()
>>> del PyClass, obj
"""
cdef public attribute
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment