Skip to content

Commit

Permalink
Merge pull request #1984 from Tiko7454/dominator-deadcode-problem-fix
Browse files Browse the repository at this point in the history
Dominator deadcode problem fix
  • Loading branch information
montyly authored Oct 12, 2023
2 parents 1e16d08 + 86f45c9 commit 7242a32
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
9 changes: 9 additions & 0 deletions slither/core/cfg/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ def __init__(
self.file_scope: "FileScope" = file_scope
self._function: Optional["Function"] = None

self._is_reachable: bool = False

###################################################################################
###################################################################################
# region General's properties
Expand Down Expand Up @@ -235,6 +237,13 @@ def set_function(self, function: "Function") -> None:
def function(self) -> "Function":
return self._function

@property
def is_reachable(self) -> bool:
return self._is_reachable

def set_is_reachable(self, new_is_reachable: bool) -> None:
self._is_reachable = new_is_reachable

# endregion
###################################################################################
###################################################################################
Expand Down
15 changes: 12 additions & 3 deletions slither/core/dominators/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@
def intersection_predecessor(node: "Node") -> Set["Node"]:
if not node.fathers:
return set()
ret = node.fathers[0].dominators
for pred in node.fathers[1:]:
ret = ret.intersection(pred.dominators)
if not any(father.is_reachable for father in node.fathers):
return set()

ret = set()
for pred in node.fathers:
ret = ret.union(pred.dominators)

for pred in node.fathers:
if pred.is_reachable:
ret = ret.intersection(pred.dominators)
return ret


Expand Down Expand Up @@ -84,6 +91,8 @@ def compute_dominance_frontier(nodes: List["Node"]) -> None:
for node in nodes:
if len(node.fathers) >= 2:
for father in node.fathers:
if not father.is_reachable:
continue
runner = father
# Corner case: if there is a if without else
# we need to add update the conditional node
Expand Down
10 changes: 10 additions & 0 deletions slither/solc_parsing/declarations/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ def analyze_content(self) -> None:

self._remove_alone_endif()

if self._function.entry_point:
self._update_reachability(self._function.entry_point)

# endregion
###################################################################################
###################################################################################
Expand Down Expand Up @@ -1102,6 +1105,13 @@ def _parse_unchecked_block(self, block: Dict, node: NodeSolc, scope):
node = self._parse_statement(statement, node, new_scope)
return node

def _update_reachability(self, node: Node) -> None:
if node.is_reachable:
return
node.set_is_reachable(True)
for son in node.sons:
self._update_reachability(son)

def _parse_cfg(self, cfg: Dict) -> None:

assert cfg[self.get_key()] == "Block"
Expand Down

0 comments on commit 7242a32

Please sign in to comment.