From 112e74e48cbba1da8c4ed7511544133286e9af2a Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Wed, 3 Sep 2008 18:24:45 +0200 Subject: [PATCH] Explicitly disallow assigning default values to struct/union members Earlier, the compiler would crash in this situation. --- Cython/Compiler/ParseTreeTransforms.py | 36 ++++++++++++++------------ tests/errors/e_cdefassign.pyx | 7 ++++- tests/errors/extclassattrsetting.pyx | 2 +- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 5150797c..895c836b 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -80,7 +80,7 @@ class NormalizeTree(CythonTransform): class PostParseError(CompileError): pass # 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_DEFAULTS = 'Invalid buffer defaults specification (see docs)' ERR_INVALID_SPECIALATTR_TYPE = 'Special attributes must not have a type declared' @@ -130,31 +130,33 @@ class PostParse(CythonTransform): def visit_ModuleNode(self, node): self.scope_type = 'module' + self.scope_node = node self.visitchildren(node) return node - - def visit_ClassDefNode(self, node): - prev = self.scope_type - self.scope_type = 'class' - self.classnode = node + + def visit_scope(self, node, scope_type): + prev = self.scope_type, self.scope_node + self.scope_type = scope_type + self.scope_node = node self.visitchildren(node) - self.scope_type = prev - del self.classnode + self.scope_type, self.scope_node = prev return node + + def visit_ClassDefNode(self, node): + return self.visit_scope(node, 'class') def visit_FuncDefNode(self, node): - prev = self.scope_type - self.scope_type = 'function' - self.visitchildren(node) - self.scope_type = prev - return node + return self.visit_scope(node, 'function') + + def visit_CStructOrUnionDefNode(self, node): + return self.visit_scope(node, 'struct') # cdef variables def handle_bufferdefaults(self, decl): if not isinstance(decl.default, DictNode): raise PostParseError(decl.pos, ERR_BUF_DEFAULTS) - self.classnode.buffer_defaults_node = decl.default - self.classnode.buffer_defaults_pos = decl.pos + self.scope_node.buffer_defaults_node = decl.default + self.scope_node.buffer_defaults_pos = decl.pos def visit_CVarDefNode(self, node): # This assumes only plain names and pointers are assignable on @@ -171,8 +173,8 @@ class PostParse(CythonTransform): declbase = declbase.base if isinstance(declbase, CNameDeclaratorNode): if declbase.default is not None: - if self.scope_type == 'class': - if isinstance(self.classnode, CClassDefNode): + if self.scope_type in ('class', 'struct'): + if isinstance(self.scope_node, CClassDefNode): handler = self.specialattribute_handlers.get(decl.name) if handler: if decl is not declbase: diff --git a/tests/errors/e_cdefassign.pyx b/tests/errors/e_cdefassign.pyx index fe66df1a..f4a38fda 100644 --- a/tests/errors/e_cdefassign.pyx +++ b/tests/errors/e_cdefassign.pyx @@ -1,6 +1,11 @@ cdef class A: cdef int value = 3 +cdef extern from *: + cdef struct B: + int value = 3 + _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 """ diff --git a/tests/errors/extclassattrsetting.pyx b/tests/errors/extclassattrsetting.pyx index 065de826..bc6cc93e 100644 --- a/tests/errors/extclassattrsetting.pyx +++ b/tests/errors/extclassattrsetting.pyx @@ -13,5 +13,5 @@ cdef class ExtClass: _attribute = 5 # FIXME: this is not currently handled!!! _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 """ -- 2.26.2