Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node API: add true/false branchs for if statement #449

Merged
merged 1 commit into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 33 additions & 21 deletions slither/core/cfg/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Node module
"""
import logging
from typing import Optional

from slither.core.children.child_function import ChildFunction
from slither.core.declarations import Contract
Expand All @@ -24,30 +25,30 @@

logger = logging.getLogger("Node")


###################################################################################
###################################################################################
# region NodeType
###################################################################################
###################################################################################

class NodeType:

ENTRYPOINT = 0x0 # no expression

# Node with expression

EXPRESSION = 0x10 # normal case
RETURN = 0x11 # RETURN may contain an expression
RETURN = 0x11 # RETURN may contain an expression
IF = 0x12
VARIABLE = 0x13 # Declaration of variable
VARIABLE = 0x13 # Declaration of variable
ASSEMBLY = 0x14
IFLOOP = 0x15

# Merging nodes
# Can have phi IR operation
ENDIF = 0x50 # ENDIF node source mapping points to the if/else body
STARTLOOP = 0x51 # STARTLOOP node source mapping points to the entire loop body
ENDLOOP = 0x52 # ENDLOOP node source mapping points to the entire loop body
ENDIF = 0x50 # ENDIF node source mapping points to the if/else body
STARTLOOP = 0x51 # STARTLOOP node source mapping points to the entire loop body
ENDLOOP = 0x52 # ENDLOOP node source mapping points to the entire loop body

# Below the nodes have no expression
# But are used to expression CFG structure
Expand All @@ -69,8 +70,7 @@ class NodeType:
# Use for state variable declaration
OTHER_ENTRYPOINT = 0x50


# @staticmethod
# @staticmethod
def str(t):
if t == NodeType.ENTRYPOINT:
return 'ENTRY_POINT'
Expand Down Expand Up @@ -118,6 +118,7 @@ def link_nodes(n1, n2):
n1.add_son(n2)
n2.add_father(n1)


def insert_node(origin, node_inserted):
sons = origin.sons
link_nodes(origin, node_inserted)
Expand All @@ -127,6 +128,7 @@ def insert_node(origin, node_inserted):

link_nodes(node_inserted, son)


def recheable(node):
'''
Return the set of nodes reacheable from the node
Expand Down Expand Up @@ -167,7 +169,7 @@ def __init__(self, node_type, node_id):
self._dominators = set()
self._immediate_dominator = None
## Nodes of the dominators tree
#self._dom_predecessors = set()
# self._dom_predecessors = set()
self._dom_successors = set()
# Dominance frontier
self._dominance_frontier = set()
Expand All @@ -189,7 +191,7 @@ def __init__(self, node_type, node_id):

self._internal_calls = []
self._solidity_calls = []
self._high_level_calls = [] # contains library calls
self._high_level_calls = [] # contains library calls
self._library_calls = []
self._low_level_calls = []
self._external_calls_as_expressions = []
Expand All @@ -207,7 +209,7 @@ def __init__(self, node_type, node_id):
self._local_vars_read = []
self._local_vars_written = []

self._slithir_vars = set() # non SSA
self._slithir_vars = set() # non SSA

self._ssa_local_vars_read = []
self._ssa_local_vars_written = []
Expand Down Expand Up @@ -396,6 +398,7 @@ def library_calls(self):
Include library calls
"""
return list(self._library_calls)

@property
def low_level_calls(self):
"""
Expand Down Expand Up @@ -547,7 +550,6 @@ def inline_asm(self):
def add_inline_asm(self, asm):
self._asm_source_code = asm


# endregion
###################################################################################
###################################################################################
Expand Down Expand Up @@ -621,6 +623,20 @@ def sons(self):
"""
return list(self._sons)

@property
def son_true(self) -> Optional["Node"]:
if self.type == NodeType.IF:
return self._sons[0]
else:
return None

@property
def son_false(self) -> Optional["Node"]:
if self.type == NodeType.IF and len(self._sons) >= 1:
return self._sons[1]
else:
return None

# endregion
###################################################################################
###################################################################################
Expand Down Expand Up @@ -648,7 +664,7 @@ def irs_ssa(self):

@irs_ssa.setter
def irs_ssa(self, irs):
self._irs_ssa = irs
self._irs_ssa = irs

def add_ssa_ir(self, ir):
'''
Expand Down Expand Up @@ -748,9 +764,6 @@ def add_phi_origin_state_variable(self, variable, node):
assert v == variable
nodes.add(node)




# endregion
###################################################################################
###################################################################################
Expand Down Expand Up @@ -789,7 +802,7 @@ def _find_read_write_call(self):
if isinstance(var, (ReferenceVariable)):
var = var.points_to_origin
if var and self._is_non_slithir_var(var):
self._vars_written.append(var)
self._vars_written.append(var)

if isinstance(ir, InternalCall):
self._internal_calls.append(ir.function)
Expand All @@ -809,7 +822,8 @@ def _find_read_write_call(self):
try:
self._high_level_calls.append((ir.destination.type.type, ir.function))
except AttributeError:
raise SlitherException(f'Function not found on {ir}. Please try compiling with a recent Solidity version.')
raise SlitherException(
f'Function not found on {ir}. Please try compiling with a recent Solidity version.')
elif isinstance(ir, LibraryCall):
assert isinstance(ir.destination, Contract)
self._high_level_calls.append((ir.destination, ir.function))
Expand Down Expand Up @@ -884,7 +898,6 @@ def update_read_write_using_ssa(self):
vars_read = [self._convert_ssa(x) for x in self._ssa_vars_read]
vars_written = [self._convert_ssa(x) for x in self._ssa_vars_written]


self._vars_read += [v for v in vars_read if v not in self._vars_read]
self._state_vars_read = [v for v in self._vars_read if isinstance(v, StateVariable)]
self._local_vars_read = [v for v in self._vars_read if isinstance(v, LocalVariable)]
Expand All @@ -893,7 +906,6 @@ def update_read_write_using_ssa(self):
self._state_vars_written = [v for v in self._vars_written if isinstance(v, StateVariable)]
self._local_vars_written = [v for v in self._vars_written if isinstance(v, LocalVariable)]


# endregion
###################################################################################
###################################################################################
Expand All @@ -902,7 +914,7 @@ def update_read_write_using_ssa(self):
###################################################################################

def __str__(self):
txt = NodeType.str(self._node_type) + ' '+ str(self.expression)
txt = NodeType.str(self._node_type) + ' ' + str(self.expression)
return txt

# endregion
12 changes: 10 additions & 2 deletions slither/core/declarations/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -1111,8 +1111,16 @@ 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)
for son in node.sons:
content += '{}->{};\n'.format(node.node_id, son.node_id)
if node.type == NodeType.IF:
true_node = node.son_true
if true_node:
content += '{}->{}[label="True"];\n'.format(node.node_id, true_node.node_id)
false_node = node.son_false
if false_node:
content += '{}->{}[label="False"];\n'.format(node.node_id, false_node.node_id)
else:
for son in node.sons:
content += '{}->{};\n'.format(node.node_id, son.node_id)

content += "}\n"
return content
Expand Down