Skip to content

Commit

Permalink
Fix interaction between static if and nested loop / function
Browse files Browse the repository at this point in the history
Fix #2263
  • Loading branch information
serge-sans-paille committed Dec 8, 2024
1 parent 4479f5a commit ffe570a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
25 changes: 25 additions & 0 deletions pythran/tests/test_none.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,31 @@ def none_loop_break_continue_or_ret(n):
return s'''
self.run_test(code, 7, none_loop_break_continue_or_ret=[int])

def test_none_loop_break_nested(self):
code = '''
def none_loop_break_nested(n):
x = [None if i%2 else 1 for i in range(n)]
s = 3
for j in x:
if j is None:
for k in x:
s += 1
continue
else:
s += 1
return s'''
self.run_test(code, 7, none_loop_break_nested=[int])

def test_none_nested_function(self):
code = '''
def none_nested_function(a):
if a is None:
return 1
def bar(x):
return [x]
return bar(a)[0]'''
self.run_test(code, 7, none_nested_function=[int])

def test_none_operators0(self):
code = '''
def helper(x):
Expand Down
18 changes: 12 additions & 6 deletions pythran/transformations/normalize_static_if.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ def outline(name, formal_parameters, out_parameters, stmts,
)
if has_return:
pr = PatchReturn(stmts[-1], has_break or has_cont)
pr.visit(fdef)
pr.generic_visit(fdef)

if has_break or has_cont:
if not has_return:
stmts[-1].value = ast.Tuple([ast.Constant(LOOP_NONE, None),
stmts[-1].value],
ast.Load())
pbc = PatchBreakContinue(stmts[-1])
pbc.visit(fdef)
pbc.generic_visit(fdef)

return fdef

Expand All @@ -66,6 +66,9 @@ def __init__(self, guard, has_break_or_cont):
self.guard = guard
self.has_break_or_cont = has_break_or_cont

def visit_FunctionDef(self, node):
return node

def visit_Return(self, node):
if node is self.guard:
holder = "StaticIfNoReturn"
Expand All @@ -92,11 +95,14 @@ class PatchBreakContinue(ast.NodeTransformer):
def __init__(self, guard):
self.guard = guard

def visit_For(self, _):
pass
def visit_FunctionDef(self, node):
return node

def visit_For(self, node):
return node

def visit_While(self, _):
pass
def visit_While(self, node):
return node

def patch_Control(self, node, flag):
new_node = deepcopy(self.guard)
Expand Down

0 comments on commit ffe570a

Please sign in to comment.