Commit 09e33cb2 authored by Mark Florisson's avatar Mark Florisson

Fix all tests and segfaults

parent ee2e8b84
...@@ -1089,6 +1089,9 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { ...@@ -1089,6 +1089,9 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
} }
static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
if (!ts) {
PyErr_SetString(PyExc_ValueError, "Got NULL buffer format");
}
int got_Z = 0; int got_Z = 0;
while (1) { while (1) {
switch(*ts) { switch(*ts) {
......
...@@ -1468,8 +1468,12 @@ class CCodeWriter(object): ...@@ -1468,8 +1468,12 @@ class CCodeWriter(object):
func = '__Pyx_RaiseUnboundLocalError' func = '__Pyx_RaiseUnboundLocalError'
self.globalstate.use_utility_code( self.globalstate.use_utility_code(
ExprNodes.raise_unbound_local_error_utility_code) ExprNodes.raise_unbound_local_error_utility_code)
self.putln('if (unlikely(!%s)) { %s("%s"); %s }' % ( self.putln('if (unlikely(!%s)) { %s("%s"); %s }' % (
entry.cname, func, entry.name, self.error_goto(pos))) entry.type.check_for_null_code(entry.cname),
func,
entry.name,
self.error_goto(pos)))
def set_error_info(self, pos): def set_error_info(self, pos):
self.funcstate.should_declare_error_indicator = True self.funcstate.should_declare_error_indicator = True
......
...@@ -1599,7 +1599,7 @@ class NameNode(AtomicExprNode): ...@@ -1599,7 +1599,7 @@ class NameNode(AtomicExprNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
elif entry.is_local or entry.in_closure or entry.from_closure: elif entry.is_local or entry.in_closure or entry.from_closure:
if entry.type.is_pyobject: if entry.type.check_for_null_code(entry.cname):
if (self.cf_maybe_null or self.cf_is_null) \ if (self.cf_maybe_null or self.cf_is_null) \
and not self.allow_null: and not self.allow_null:
code.put_error_if_unbound(self.pos, entry) code.put_error_if_unbound(self.pos, entry)
......
...@@ -19,11 +19,17 @@ INVALID_ERR = "Invalid axis specification." ...@@ -19,11 +19,17 @@ INVALID_ERR = "Invalid axis specification."
EXPR_ERR = "no expressions allowed in axis spec, only names (e.g. cython.view.contig)." EXPR_ERR = "no expressions allowed in axis spec, only names (e.g. cython.view.contig)."
CF_ERR = "Invalid axis specification for a C/Fortran contiguous array." CF_ERR = "Invalid axis specification for a C/Fortran contiguous array."
memview_c_contiguous = "PyBUF_C_CONTIGUOUS" def concat_flags(*flags):
memview_f_contiguous = "PyBUF_F_CONTIGUOUS" return "(%s)" % "|".join(flags)
memview_any_contiguous = "PyBUF_ANY_CONTIGUOUS"
format_flag = "PyBUF_FORMAT"
memview_c_contiguous = concat_flags(format_flag, "PyBUF_C_CONTIGUOUS")
memview_f_contiguous = concat_flags(format_flag, "PyBUF_F_CONTIGUOUS")
memview_any_contiguous = concat_flags(format_flag, "PyBUF_ANY_CONTIGUOUS")
memview_full_access = "PyBUF_FULL" memview_full_access = "PyBUF_FULL"
memview_strided_access = "PyBUF_STRIDED" #memview_strided_access = "PyBUF_STRIDED"
memview_strided_access = "PyBUF_RECORDS"
MEMVIEW_DIRECT = 1 MEMVIEW_DIRECT = 1
MEMVIEW_PTR = 2 MEMVIEW_PTR = 2
...@@ -41,6 +47,7 @@ _spec_to_const = { ...@@ -41,6 +47,7 @@ _spec_to_const = {
'full' : MEMVIEW_FULL 'full' : MEMVIEW_FULL
} }
def specs_to_code(specs): def specs_to_code(specs):
arr = [] arr = []
for access, packing in specs: for access, packing in specs:
......
...@@ -27,6 +27,14 @@ class BaseType(object): ...@@ -27,6 +27,14 @@ class BaseType(object):
else: else:
return base_code return base_code
def check_for_null_code(self, cname):
"""
Return the code for a NULL-check in case an UnboundLocalError should
be raised if an entry of this type is referenced before assignment.
Returns None if no check should be performed.
"""
return None
def invalid_value(self): def invalid_value(self):
""" """
Returns the most invalid value an object of this type can assume as a Returns the most invalid value an object of this type can assume as a
...@@ -461,9 +469,14 @@ class MemoryViewSliceType(PyrexType): ...@@ -461,9 +469,14 @@ class MemoryViewSliceType(PyrexType):
is_contig_name = \ is_contig_name = \
MemoryView.get_is_contig_func_name(c_or_f) MemoryView.get_is_contig_func_name(c_or_f)
cfunctype = CFuncType(
return_type=c_int_type,
args=[CFuncTypeArg("memviewslice", self, None)],
exception_value="-1",
)
entry = scope.declare_cfunction(cython_name, entry = scope.declare_cfunction(cython_name,
CFuncType(c_int_type, cfunctype,
[CFuncTypeArg("memviewslice", self, None)]),
pos = None, pos = None,
defining = 1, defining = 1,
cname = is_contig_name) cname = is_contig_name)
...@@ -482,6 +495,9 @@ class MemoryViewSliceType(PyrexType): ...@@ -482,6 +495,9 @@ class MemoryViewSliceType(PyrexType):
code.putln("%s.data = NULL;" % entry.cname) code.putln("%s.data = NULL;" % entry.cname)
code.put_init_to_py_none("%s.memview" % entry.cname, cython_memoryview_ptr_type, nanny=False) code.put_init_to_py_none("%s.memview" % entry.cname, cython_memoryview_ptr_type, nanny=False)
def check_for_null_code(self, cname):
return cname + '.memview'
class BufferType(BaseType): class BufferType(BaseType):
# #
# Delegates most attribute # Delegates most attribute
...@@ -568,6 +584,9 @@ class PyObjectType(PyrexType): ...@@ -568,6 +584,9 @@ class PyObjectType(PyrexType):
def global_init_code(self, entry, code): def global_init_code(self, entry, code):
code.put_init_var_to_py_none(entry, nanny=False) code.put_init_var_to_py_none(entry, nanny=False)
def check_for_null_code(self, cname):
return cname
class BuiltinObjectType(PyObjectType): class BuiltinObjectType(PyObjectType):
# objstruct_cname string Name of PyObject struct # objstruct_cname string Name of PyObject struct
......
...@@ -75,7 +75,7 @@ def test_nonecheck1(): ...@@ -75,7 +75,7 @@ def test_nonecheck1():
>>> test_nonecheck1() >>> test_nonecheck1()
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: 'NoneType' object has no attribute 'is_c_contig' UnboundLocalError: local variable 'uninitialized' referenced before assignment
''' '''
cdef int[:,:,:] uninitialized cdef int[:,:,:] uninitialized
print uninitialized.is_c_contig() print uninitialized.is_c_contig()
...@@ -87,7 +87,7 @@ def test_nonecheck2(): ...@@ -87,7 +87,7 @@ def test_nonecheck2():
>>> test_nonecheck2() >>> test_nonecheck2()
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: 'NoneType' object has no attribute 'is_f_contig' UnboundLocalError: local variable 'uninitialized' referenced before assignment
''' '''
cdef int[:,:,:] uninitialized cdef int[:,:,:] uninitialized
print uninitialized.is_f_contig() print uninitialized.is_f_contig()
...@@ -99,7 +99,7 @@ def test_nonecheck3(): ...@@ -99,7 +99,7 @@ def test_nonecheck3():
>>> test_nonecheck3() >>> test_nonecheck3()
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: 'NoneType' object has no attribute 'copy' UnboundLocalError: local variable 'uninitialized' referenced before assignment
''' '''
cdef int[:,:,:] uninitialized cdef int[:,:,:] uninitialized
uninitialized.copy() uninitialized.copy()
...@@ -111,7 +111,7 @@ def test_nonecheck4(): ...@@ -111,7 +111,7 @@ def test_nonecheck4():
>>> test_nonecheck4() >>> test_nonecheck4()
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: 'NoneType' object has no attribute 'copy_fortran' UnboundLocalError: local variable 'uninitialized' referenced before assignment
''' '''
cdef int[:,:,:] uninitialized cdef int[:,:,:] uninitialized
uninitialized.copy_fortran() uninitialized.copy_fortran()
...@@ -123,7 +123,7 @@ def test_nonecheck5(): ...@@ -123,7 +123,7 @@ def test_nonecheck5():
>>> test_nonecheck5() >>> test_nonecheck5()
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: 'NoneType' object has no attribute '_data' UnboundLocalError: local variable 'uninitialized' referenced before assignment
''' '''
cdef int[:,:,:] uninitialized cdef int[:,:,:] uninitialized
uninitialized._data uninitialized._data
......
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