Add unchecked block information + add checked arithmetic info

pull/837/head
Josselin 4 years ago
parent f797166e0f
commit 5319654922
  1. 5
      slither/slithir/operations/binary.py
  2. 27
      slither/solc_parsing/declarations/function.py

@ -88,6 +88,9 @@ class BinaryType(Enum):
raise SlithIRError("get_type: Unknown operation type {})".format(operation_type)) raise SlithIRError("get_type: Unknown operation type {})".format(operation_type))
def can_be_checked_for_overflow(self):
return self in [BinaryType.POWER, BinaryType.MULTIPLICATION, BinaryType.MODULO, BinaryType.ADDITION, BinaryType.SUBTRACTION, BinaryType.DIVISION]
def __str__(self): # pylint: disable=too-many-branches def __str__(self): # pylint: disable=too-many-branches
if self == BinaryType.POWER: if self == BinaryType.POWER:
return "**" return "**"
@ -168,6 +171,8 @@ class Binary(OperationWithLValue):
@property @property
def type_str(self): def type_str(self):
if self.node.scope.is_checked and self._type.can_be_checked_for_overflow():
return '(c)' + str(self._type)
return str(self._type) return str(self._type)
def __str__(self): def __str__(self):

@ -881,6 +881,8 @@ class FunctionSolc:
node = self._parse_for(statement, node) node = self._parse_for(statement, node)
elif name == "Block": elif name == "Block":
node = self._parse_block(statement, node) node = self._parse_block(statement, node)
elif name == "UncheckedBlock":
node = self._parse_unchecked_block(statement, node)
elif name == "InlineAssembly": elif name == "InlineAssembly":
# Added with solc 0.6 - the yul code is an AST # Added with solc 0.6 - the yul code is an AST
if "AST" in statement and not self.compilation_unit.core.skip_assembly: if "AST" in statement and not self.compilation_unit.core.skip_assembly:
@ -965,7 +967,7 @@ class FunctionSolc:
return node return node
def _parse_block(self, block: Dict, node: NodeSolc): def _parse_block(self, block: Dict, node: NodeSolc, check_arithmetic:bool = False):
""" """
Return: Return:
Node Node
@ -977,7 +979,25 @@ class FunctionSolc:
else: else:
statements = block[self.get_children("children")] statements = block[self.get_children("children")]
new_scope = Scope(node.underlying_node.scope.is_checked, False, node.underlying_node.scope) check_arithmetic = check_arithmetic | node.underlying_node.scope.is_checked
new_scope = Scope(check_arithmetic, False, node.underlying_node.scope)
for statement in statements:
node = self._parse_statement(statement, node, new_scope)
return node
def _parse_unchecked_block(self, block: Dict, node: NodeSolc):
"""
Return:
Node
"""
assert block[self.get_key()] == "UncheckedBlock"
if self.is_compact_ast:
statements = block["statements"]
else:
statements = block[self.get_children("children")]
new_scope = Scope(False, False, node.underlying_node.scope)
for statement in statements: for statement in statements:
node = self._parse_statement(statement, node, new_scope) node = self._parse_statement(statement, node, new_scope)
return node return node
@ -998,7 +1018,8 @@ class FunctionSolc:
self._function.is_empty = True self._function.is_empty = True
else: else:
self._function.is_empty = False self._function.is_empty = False
self._parse_block(cfg, node) check_arithmetic = self.compilation_unit.solc_version >= "0.8.0"
self._parse_block(cfg, node, check_arithmetic=check_arithmetic)
self._remove_incorrect_edges() self._remove_incorrect_edges()
self._remove_alone_endif() self._remove_alone_endif()

Loading…
Cancel
Save