Commit 4b5babd8 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Proper nogil checks for buffer access

parent bc297512
...@@ -1745,7 +1745,6 @@ class IndexNode(ExprNode): ...@@ -1745,7 +1745,6 @@ class IndexNode(ExprNode):
else: else:
self.index = self.index.coerce_to_pyobject(env) self.index = self.index.coerce_to_pyobject(env)
self.type = py_object_type self.type = py_object_type
self.gil_check(env)
self.is_temp = 1 self.is_temp = 1
else: else:
if self.base.type.is_ptr or self.base.type.is_array: if self.base.type.is_ptr or self.base.type.is_array:
...@@ -1762,9 +1761,21 @@ class IndexNode(ExprNode): ...@@ -1762,9 +1761,21 @@ class IndexNode(ExprNode):
error(self.pos, error(self.pos,
"Invalid index type '%s'" % "Invalid index type '%s'" %
self.index.type) self.index.type)
self.gil_check(env)
gil_message = "Indexing Python object" gil_message = "Indexing Python object"
def gil_check(self, env):
if self.is_buffer_access and env.nogil:
if env.directives['boundscheck']:
error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
return
elif self.type.is_pyobject:
error(self.pos, "Cannot access buffer with object dtype without gil")
return
super(IndexNode, self).gil_check(env)
def check_const_addr(self): def check_const_addr(self):
self.base.check_const_addr() self.base.check_const_addr()
self.index.check_const() self.index.check_const()
......
cimport e_bufaccess_pxd # was needed to provoke a bug involving ErrorType cimport e_bufaccess_pxd # was needed to provoke a bug involving ErrorType
import cython
def f(): def f():
cdef object[e_bufaccess_pxd.T] buf cdef object[e_bufaccess_pxd.T] buf
def withnogil_access_fail():
cdef object[int] buf = None
with nogil:
buf[2] = 2
@cython.boundscheck(False)
def withnogil_access_ok():
cdef object[int] buf = None
with nogil:
buf[2] = 2 # No error should be triggered here
@cython.boundscheck(False)
def withnogil_access_fail_2():
cdef object[object] buf = None
with nogil:
buf[2] = 2 # Not OK as dtype is object
def withnogil_acquire(x):
cdef object[int] buf
with nogil:
buf = x
_ERRORS = u""" _ERRORS = u"""
3:9: 'nothing' is not a type identifier 3:9: 'nothing' is not a type identifier
10:11: Cannot check buffer index bounds without gil; use boundscheck(False) directive
22:11: Cannot access buffer with object dtype without gil
22:11: Assignment of Python object not allowed without gil
27:12: Assignment of Python object not allowed without gil
""" """
...@@ -1449,3 +1449,18 @@ def complex_struct_inplace(object[LongComplex] buf): ...@@ -1449,3 +1449,18 @@ def complex_struct_inplace(object[LongComplex] buf):
buf[0].imag += 2 buf[0].imag += 2
print buf[0].real, buf[0].imag print buf[0].real, buf[0].imag
#
# Nogil
#
@testcase
@cython.boundscheck(False)
def buffer_nogil():
"""
>>> buffer_nogil()
10
"""
cdef object[int] buf = IntMockBuffer(None, [1,2,3])
with nogil:
buf[1] = 10
return buf[1]
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