Commit 112e74e4 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Explicitly disallow assigning default values to struct/union members

Earlier, the compiler would crash in this situation.
parent 7e871646
...@@ -80,7 +80,7 @@ class NormalizeTree(CythonTransform): ...@@ -80,7 +80,7 @@ class NormalizeTree(CythonTransform):
class PostParseError(CompileError): pass class PostParseError(CompileError): pass
# error strings checked by unit tests, so define them # error strings checked by unit tests, so define them
ERR_CDEF_INCLASS = 'Cannot assign default value to cdef class attributes' ERR_CDEF_INCLASS = 'Cannot assign default value to fields in cdef classes, structs or unions'
ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables' ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables'
ERR_BUF_DEFAULTS = 'Invalid buffer defaults specification (see docs)' ERR_BUF_DEFAULTS = 'Invalid buffer defaults specification (see docs)'
ERR_INVALID_SPECIALATTR_TYPE = 'Special attributes must not have a type declared' ERR_INVALID_SPECIALATTR_TYPE = 'Special attributes must not have a type declared'
...@@ -130,31 +130,33 @@ class PostParse(CythonTransform): ...@@ -130,31 +130,33 @@ class PostParse(CythonTransform):
def visit_ModuleNode(self, node): def visit_ModuleNode(self, node):
self.scope_type = 'module' self.scope_type = 'module'
self.scope_node = node
self.visitchildren(node) self.visitchildren(node)
return node return node
def visit_ClassDefNode(self, node): def visit_scope(self, node, scope_type):
prev = self.scope_type prev = self.scope_type, self.scope_node
self.scope_type = 'class' self.scope_type = scope_type
self.classnode = node self.scope_node = node
self.visitchildren(node) self.visitchildren(node)
self.scope_type = prev self.scope_type, self.scope_node = prev
del self.classnode
return node return node
def visit_ClassDefNode(self, node):
return self.visit_scope(node, 'class')
def visit_FuncDefNode(self, node): def visit_FuncDefNode(self, node):
prev = self.scope_type return self.visit_scope(node, 'function')
self.scope_type = 'function'
self.visitchildren(node) def visit_CStructOrUnionDefNode(self, node):
self.scope_type = prev return self.visit_scope(node, 'struct')
return node
# cdef variables # cdef variables
def handle_bufferdefaults(self, decl): def handle_bufferdefaults(self, decl):
if not isinstance(decl.default, DictNode): if not isinstance(decl.default, DictNode):
raise PostParseError(decl.pos, ERR_BUF_DEFAULTS) raise PostParseError(decl.pos, ERR_BUF_DEFAULTS)
self.classnode.buffer_defaults_node = decl.default self.scope_node.buffer_defaults_node = decl.default
self.classnode.buffer_defaults_pos = decl.pos self.scope_node.buffer_defaults_pos = decl.pos
def visit_CVarDefNode(self, node): def visit_CVarDefNode(self, node):
# This assumes only plain names and pointers are assignable on # This assumes only plain names and pointers are assignable on
...@@ -171,8 +173,8 @@ class PostParse(CythonTransform): ...@@ -171,8 +173,8 @@ class PostParse(CythonTransform):
declbase = declbase.base declbase = declbase.base
if isinstance(declbase, CNameDeclaratorNode): if isinstance(declbase, CNameDeclaratorNode):
if declbase.default is not None: if declbase.default is not None:
if self.scope_type == 'class': if self.scope_type in ('class', 'struct'):
if isinstance(self.classnode, CClassDefNode): if isinstance(self.scope_node, CClassDefNode):
handler = self.specialattribute_handlers.get(decl.name) handler = self.specialattribute_handlers.get(decl.name)
if handler: if handler:
if decl is not declbase: if decl is not declbase:
......
cdef class A: cdef class A:
cdef int value = 3 cdef int value = 3
cdef extern from *:
cdef struct B:
int value = 3
_ERRORS = u""" _ERRORS = u"""
2:13: Cannot assign default value to cdef class attributes 2:13: Cannot assign default value to fields in cdef classes, structs or unions
6:12: Cannot assign default value to fields in cdef classes, structs or unions
""" """
...@@ -13,5 +13,5 @@ cdef class ExtClass: ...@@ -13,5 +13,5 @@ cdef class ExtClass:
_attribute = 5 # FIXME: this is not currently handled!!! _attribute = 5 # FIXME: this is not currently handled!!!
_ERRORS = u""" _ERRORS = u"""
8:13: Cannot assign default value to cdef class attributes 8:13: Cannot assign default value to fields in cdef classes, structs or unions
""" """
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