Skip to content

Commit

Permalink
fix: termination analysis inside of For nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
charles-cooper committed Jan 14, 2024
1 parent d5c94a9 commit ac4296e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
40 changes: 40 additions & 0 deletions tests/functional/syntax/test_unbalanced_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,39 @@ def foo() -> uint256:
""",
StructureException,
),
(
"""
@internal
def foo() -> uint256:
for i: uint256 in range(10):
if i == 11:
return 1
""",
FunctionDeclarationException,
),
(
"""
@internal
def foo() -> uint256:
for i: uint256 in range(9):
if i == 11:
return 1
if block.number % 2 == 0:
return 1
""",
FunctionDeclarationException,
),
(
"""
@internal
def foo() -> uint256:
for i: uint256 in range(10):
return 1
pass # unreachable
return 5
""",
StructureException,
),
]


Expand Down Expand Up @@ -187,6 +220,13 @@ def foo() -> int128:
else:
raw_revert(b"vyper")
""",
"""
@external
def foo() -> int128:
for i: uint256 in range(1):
return 1
return 0
""",
]


Expand Down
5 changes: 5 additions & 0 deletions vyper/semantics/analysis/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def find_terminating_node(node_list: list) -> Optional[vy_ast.VyperNode]:
for node in node_list:
if ret is not None:
raise StructureException("Unreachable code!", node)

if node.is_terminus:
ret = node

Expand All @@ -87,6 +88,10 @@ def find_terminating_node(node_list: list) -> Optional[vy_ast.VyperNode]:
if body_terminates is not None and else_terminates is not None:
ret = else_terminates

if isinstance(node, vy_ast.For):
# call find_terminating_node for its side effects
find_terminating_node(node.body)

return ret


Expand Down

0 comments on commit ac4296e

Please sign in to comment.