cython-devel
changeset 1870:478a5cfba350
Bug 158 -- raise error if cdef variable declared after it's used.
| author | Kurt Smith <kwsmith1@wisc.edu> |
|---|---|
| date | Tue Mar 17 00:02:46 2009 -0500 (2 years ago) |
| parents | 137b3d0a0c60 |
| children | e2365a6d00b8 |
| files | Cython/Compiler/ParseTreeTransforms.py tests/errors/declareafteruse_T158.pyx |
line diff
1.1 --- a/Cython/Compiler/ParseTreeTransforms.py Mon Mar 16 21:33:46 2009 +0100
1.2 +++ b/Cython/Compiler/ParseTreeTransforms.py Tue Mar 17 00:02:46 2009 -0500
1.3 @@ -658,6 +658,8 @@
1.4 rhs = decorator_result)
1.5 return [func_node, reassignment]
1.6
1.7 +
1.8 +ERR_DEC_AFTER = "cdef variable '%s' declared after it's used."
1.9 class AnalyseDeclarationsTransform(CythonTransform):
1.10
1.11 basic_property = TreeFragment(u"""
1.12 @@ -670,14 +672,23 @@
1.13
1.14 def __call__(self, root):
1.15 self.env_stack = [root.scope]
1.16 + # needed to determine if a cdef var is declared after it's used.
1.17 + self.local_scope_stack = []
1.18 return super(AnalyseDeclarationsTransform, self).__call__(root)
1.19
1.20 + def visit_NameNode(self, node):
1.21 + self.local_scope_stack[-1].add(node.name)
1.22 + return node
1.23 +
1.24 def visit_ModuleNode(self, node):
1.25 + self.local_scope_stack.append(set())
1.26 node.analyse_declarations(self.env_stack[-1])
1.27 self.visitchildren(node)
1.28 + self.local_scope_stack.pop()
1.29 return node
1.30
1.31 def visit_FuncDefNode(self, node):
1.32 + self.local_scope_stack.append(set())
1.33 lenv = node.create_local_scope(self.env_stack[-1])
1.34 node.body.analyse_control_flow(lenv) # this will be totally refactored
1.35 node.declare_arguments(lenv)
1.36 @@ -692,6 +703,7 @@
1.37 self.env_stack.append(lenv)
1.38 self.visitchildren(node)
1.39 self.env_stack.pop()
1.40 + self.local_scope_stack.pop()
1.41 return node
1.42
1.43 # Some nodes are no longer needed after declaration
1.44 @@ -699,6 +711,8 @@
1.45 # on these nodes in a seperate recursive process from the
1.46 # enclosing function or module, so we can simply drop them.
1.47 def visit_CDeclaratorNode(self, node):
1.48 + # necessary to ensure that all CNameDeclaratorNodes are visited.
1.49 + self.visitchildren(node)
1.50 return node
1.51
1.52 def visit_CTypeDefNode(self, node):
1.53 @@ -713,7 +727,18 @@
1.54 def visit_CStructOrUnionDefNode(self, node):
1.55 return None
1.56
1.57 + def visit_CNameDeclaratorNode(self, node):
1.58 + if node.name in self.local_scope_stack[-1]:
1.59 + # cdef variable declared after it's used.
1.60 + error(node.pos, ERR_DEC_AFTER % node.name)
1.61 + self.visitchildren(node)
1.62 + return node
1.63 +
1.64 def visit_CVarDefNode(self, node):
1.65 +
1.66 + # to ensure all CNameDeclaratorNodes are visited.
1.67 + self.visitchildren(node)
1.68 +
1.69 if node.need_properties:
1.70 # cdef public attributes may need type testing on
1.71 # assignment, so we create a property accesss
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/tests/errors/declareafteruse_T158.pyx Tue Mar 17 00:02:46 2009 -0500
2.3 @@ -0,0 +1,65 @@
2.4 +def mult_decl_test():
2.5 + print "%s" % vv
2.6 + print "%s" % s
2.7 + cdef str s, vv = "Test"
2.8 +
2.9 +def def_test():
2.10 + cdef int j = 10
2.11 + i[0] = j
2.12 + cdef int *i = NULL # pointer variables are special case
2.13 +
2.14 +cdef cdef_test():
2.15 + cdef int j = 10
2.16 + i[0] = j
2.17 + print "%d" % i[0]
2.18 + cdef int *i = NULL
2.19 +
2.20 +cpdef cpdef_test():
2.21 + cdef int j = 10
2.22 + i[0] = j
2.23 + print "%d" % i[0]
2.24 + cdef int *i = NULL
2.25 +
2.26 +s.upper()
2.27 +cdef str s = "Test"
2.28 +
2.29 +class Foo(object):
2.30 + def bar(self, x, y):
2.31 + cdef unsigned long w = 20
2.32 + z = w + t
2.33 + cdef int t = 10
2.34 +
2.35 +cdef class Foo2(object):
2.36 + print '%s' % r # check error inside class scope
2.37 + cdef str r
2.38 + def bar(self, x, y):
2.39 + cdef unsigned long w = 20
2.40 + self.r = c'r'
2.41 + print self.r
2.42 + z = w + g(t)
2.43 + cdef int t = 10
2.44 +
2.45 +def g(x):
2.46 + return x
2.47 +
2.48 +cdef int d = 20
2.49 +baz[0] = d
2.50 +cdef int *baz
2.51 +
2.52 +print var[0][0]
2.53 +cdef unsigned long long var[100][100]
2.54 +
2.55 +
2.56 +_ERRORS = u"""
2.57 +4:13: cdef variable 's' declared after it's used.
2.58 +4:16: cdef variable 'vv' declared after it's used.
2.59 +9:14: cdef variable 'i' declared after it's used.
2.60 +15:14: cdef variable 'i' declared after it's used.
2.61 +21:14: cdef variable 'i' declared after it's used.
2.62 +24:9: cdef variable 's' declared after it's used.
2.63 +30:17: cdef variable 't' declared after it's used.
2.64 +34:13: cdef variable 'r' declared after it's used.
2.65 +40:17: cdef variable 't' declared after it's used.
2.66 +47:10: cdef variable 'baz' declared after it's used.
2.67 +50:24: cdef variable 'var' declared after it's used.
2.68 +"""
