diff --git a/slither/core/cfg/node.py b/slither/core/cfg/node.py index f5ccef2db7..f8dbe87ce9 100644 --- a/slither/core/cfg/node.py +++ b/slither/core/cfg/node.py @@ -650,13 +650,13 @@ def sons(self) -> List["Node"]: @property def son_true(self) -> Optional["Node"]: - if self.type == NodeType.IF: + if self.type in [NodeType.IF, NodeType.IFLOOP]: return self._sons[0] return None @property def son_false(self) -> Optional["Node"]: - if self.type == NodeType.IF and len(self._sons) >= 1: + if self.type in [NodeType.IF, NodeType.IFLOOP] and len(self._sons) >= 1: return self._sons[1] return None diff --git a/slither/core/declarations/function.py b/slither/core/declarations/function.py index d28dabb2c6..b21fbe9338 100644 --- a/slither/core/declarations/function.py +++ b/slither/core/declarations/function.py @@ -1282,7 +1282,7 @@ def slithir_cfg_to_dot_str(self) -> str: if node.irs: label += "\nIRs:\n" + "\n".join([str(ir) for ir in node.irs]) content += '{}[label="{}"];\n'.format(node.node_id, label) - if node.type == NodeType.IF: + if node.type in [NodeType.IF, NodeType.IFLOOP]: true_node = node.son_true if true_node: content += '{}->{}[label="True"];\n'.format(node.node_id, true_node.node_id) diff --git a/slither/solc_parsing/declarations/function.py b/slither/solc_parsing/declarations/function.py index 4572c6766c..fafa4527aa 100644 --- a/slither/solc_parsing/declarations/function.py +++ b/slither/solc_parsing/declarations/function.py @@ -398,18 +398,24 @@ def _parse_for_compact_ast(self, statement: Dict, node: NodeSolc) -> NodeSolc: node_condition = self._new_node(NodeType.IFLOOP, condition["src"]) node_condition.add_unparsed_expression(condition) link_underlying_nodes(node_startLoop, node_condition) - link_underlying_nodes(node_condition, node_endLoop) + + node_beforeBody = node_condition else: - node_condition = node_startLoop + node_condition = None + + node_beforeBody = node_startLoop + + node_body = self._parse_statement(body, node_beforeBody) - node_body = self._parse_statement(body, node_condition) + if node_condition: + link_underlying_nodes(node_condition, node_endLoop) node_LoopExpression = None if loop_expression: node_LoopExpression = self._parse_statement(loop_expression, node_body) - link_underlying_nodes(node_LoopExpression, node_condition) + link_underlying_nodes(node_LoopExpression, node_beforeBody) else: - link_underlying_nodes(node_body, node_condition) + link_underlying_nodes(node_body, node_beforeBody) if not condition: if not loop_expression: @@ -497,13 +503,15 @@ def _parse_for(self, statement: Dict, node: NodeSolc) -> NodeSolc: # expression = parse_expression(candidate, self) node_condition.add_unparsed_expression(expression) link_underlying_nodes(node_startLoop, node_condition) - link_underlying_nodes(node_condition, node_endLoop) hasCondition = True else: hasCondition = False node_statement = self._parse_statement(children[-1], node_condition) + if hasCondition: + link_underlying_nodes(node_condition, node_endLoop) + node_LoopExpression = node_statement if hasLoopExpression: if len(children) > 2: