Commit eb64d91c authored by Mark Florisson's avatar Mark Florisson

Support module level control flow and Entry-level error on uninitialized

parent 9e1e1ffe
...@@ -145,7 +145,7 @@ class ControlFlow(object): ...@@ -145,7 +145,7 @@ class ControlFlow(object):
if entry.type.is_array or entry.type.is_struct_or_union: if entry.type.is_array or entry.type.is_struct_or_union:
return False return False
return (entry.is_local or entry.is_pyclass_attr or entry.is_arg or return (entry.is_local or entry.is_pyclass_attr or entry.is_arg or
entry.from_closure or entry.in_closure) entry.from_closure or entry.in_closure or entry.error_on_uninitialized)
def mark_position(self, node): def mark_position(self, node):
"""Mark position, will be used to draw graph nodes.""" """Mark position, will be used to draw graph nodes."""
...@@ -479,7 +479,8 @@ def check_definitions(flow, compiler_directives): ...@@ -479,7 +479,8 @@ def check_definitions(flow, compiler_directives):
if node.allow_null or entry.from_closure: if node.allow_null or entry.from_closure:
pass # Can be uninitialized here pass # Can be uninitialized here
elif node.cf_is_null: elif node.cf_is_null:
if entry.type.is_pyobject or entry.type.is_unspecified: if (entry.type.is_pyobject or entry.type.is_unspecified or
entry.error_on_uninitialized):
messages.error( messages.error(
node.pos, node.pos,
"local variable '%s' referenced before assignment" "local variable '%s' referenced before assignment"
...@@ -551,15 +552,22 @@ class AssignmentCollector(TreeVisitor): ...@@ -551,15 +552,22 @@ class AssignmentCollector(TreeVisitor):
class CreateControlFlowGraph(CythonTransform): class CreateControlFlowGraph(CythonTransform):
"""Create NameNode use and assignment graph.""" """Create NameNode use and assignment graph."""
in_inplace_assignment = False
def visit_ModuleNode(self, node): def visit_ModuleNode(self, node):
self.gv_ctx = GVContext() self.gv_ctx = GVContext()
# Set of NameNode reductions
self.reductions = cython.set()
self.env_stack = [] self.env_stack = []
self.env = node.scope self.env = node.scope
self.stack = [] self.stack = []
self.flow = ControlFlow() self.flow = ControlFlow()
self.visitchildren(node) self.visitchildren(node)
check_definitions(self.flow, self.current_directives)
dot_output = self.current_directives['control_flow.dot_output'] dot_output = self.current_directives['control_flow.dot_output']
if dot_output: if dot_output:
annotate_defs = self.current_directives['control_flow.dot_annotate_defs'] annotate_defs = self.current_directives['control_flow.dot_annotate_defs']
......
...@@ -125,6 +125,8 @@ class Entry(object): ...@@ -125,6 +125,8 @@ class Entry(object):
# utility_code_definition For some Cython builtins, the utility code # utility_code_definition For some Cython builtins, the utility code
# which contains the definition of the entry. # which contains the definition of the entry.
# Currently only supported for CythonScope entries. # Currently only supported for CythonScope entries.
# error_on_uninitialized Have Control Flow issue an error when this entry is
# used uninitialized
inline_func_in_pxd = False inline_func_in_pxd = False
borrowed = 0 borrowed = 0
...@@ -179,6 +181,7 @@ class Entry(object): ...@@ -179,6 +181,7 @@ class Entry(object):
utility_code_definition = None utility_code_definition = None
in_with_gil_block = 0 in_with_gil_block = 0
from_cython_utility_code = None from_cython_utility_code = None
error_on_uninitialized = False
def __init__(self, name, cname, type, pos = None, init = None): def __init__(self, name, cname, type, pos = None, init = None):
self.name = name self.name = name
......
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