|
|
@ -1149,16 +1149,38 @@ class FunctionSolc(CallerContextExpression): |
|
|
|
|
|
|
|
|
|
|
|
return None |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
def _find_if_loop(self, node: Node, visited: List[Node]) -> Optional[Node]: |
|
|
|
def _find_if_loop(self, node: Node, visited: List[Node], skip_if_loop: int) -> Optional[Node]: |
|
|
|
if node in visited: |
|
|
|
if node in visited: |
|
|
|
return None |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# If skip_if_loop is not 0 it means we are in a nested situation |
|
|
|
|
|
|
|
# and we have to skip the closer n loop headers. |
|
|
|
|
|
|
|
# If in the fathers there is an EXPRESSION node it's a for loop |
|
|
|
|
|
|
|
# and it's the index increment expression |
|
|
|
if node.type == NodeType.IFLOOP: |
|
|
|
if node.type == NodeType.IFLOOP: |
|
|
|
return node |
|
|
|
if skip_if_loop == 0: |
|
|
|
|
|
|
|
for father in node.fathers: |
|
|
|
|
|
|
|
if father.type == NodeType.EXPRESSION: |
|
|
|
|
|
|
|
return father |
|
|
|
|
|
|
|
return node |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# skip_if_loop works as explained above. |
|
|
|
|
|
|
|
# This handle when a for loop doesn't have a condition |
|
|
|
|
|
|
|
# e.g. for (;;) {} |
|
|
|
|
|
|
|
# and decrement skip_if_loop since we are out of the nested loop |
|
|
|
|
|
|
|
if node.type == NodeType.STARTLOOP: |
|
|
|
|
|
|
|
if skip_if_loop == 0: |
|
|
|
|
|
|
|
return node |
|
|
|
|
|
|
|
skip_if_loop -= 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# If we find an ENDLOOP means we are in a nested loop |
|
|
|
|
|
|
|
# we increment skip_if_loop counter |
|
|
|
|
|
|
|
if node.type == NodeType.ENDLOOP: |
|
|
|
|
|
|
|
skip_if_loop += 1 |
|
|
|
|
|
|
|
|
|
|
|
visited = visited + [node] |
|
|
|
visited = visited + [node] |
|
|
|
for father in node.fathers: |
|
|
|
for father in node.fathers: |
|
|
|
ret = self._find_if_loop(father, visited) |
|
|
|
ret = self._find_if_loop(father, visited, skip_if_loop) |
|
|
|
if ret: |
|
|
|
if ret: |
|
|
|
return ret |
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
|
@ -1181,7 +1203,7 @@ class FunctionSolc(CallerContextExpression): |
|
|
|
end_node.add_father(node) |
|
|
|
end_node.add_father(node) |
|
|
|
|
|
|
|
|
|
|
|
def _fix_continue_node(self, node: Node) -> None: |
|
|
|
def _fix_continue_node(self, node: Node) -> None: |
|
|
|
if_loop_node = self._find_if_loop(node, []) |
|
|
|
if_loop_node = self._find_if_loop(node, [], 0) |
|
|
|
|
|
|
|
|
|
|
|
if not if_loop_node: |
|
|
|
if not if_loop_node: |
|
|
|
raise ParsingError(f"Continue in no-loop context {node.node_id}") |
|
|
|
raise ParsingError(f"Continue in no-loop context {node.node_id}") |
|
|
|