Improve slithIR RETURN conversion (close #89)

pull/108/head
Josselin 6 years ago
parent 39d88e119a
commit 8248bba943
  1. 11
      slither/slithir/convert.py
  2. 20
      slither/slithir/operations/return_operation.py
  3. 5
      slither/visitors/slithir/expression_to_slithir.py

@ -2,7 +2,7 @@ import logging
from slither.core.declarations import (Contract, Enum, Event, SolidityFunction, from slither.core.declarations import (Contract, Enum, Event, SolidityFunction,
Structure, SolidityVariableComposed, Function, SolidityVariable) Structure, SolidityVariableComposed, Function, SolidityVariable)
from slither.core.expressions import Identifier, Literal from slither.core.expressions import Identifier, Literal, TupleExpression
from slither.core.solidity_types import ElementaryType, UserDefinedType, MappingType, ArrayType, FunctionType from slither.core.solidity_types import ElementaryType, UserDefinedType, MappingType, ArrayType, FunctionType
from slither.core.variables.variable import Variable from slither.core.variables.variable import Variable
from slither.slithir.operations import (Assignment, Binary, BinaryType, Call, from slither.slithir.operations import (Assignment, Binary, BinaryType, Call,
@ -667,18 +667,15 @@ def convert_expression(expression, node):
# handle standlone expression # handle standlone expression
# such as return true; # such as return true;
from slither.core.cfg.node import NodeType from slither.core.cfg.node import NodeType
if isinstance(expression, Literal) and node.type == NodeType.RETURN:
result = [Return(Constant(expression.value))]
return result
if isinstance(expression, Identifier) and node.type == NodeType.RETURN:
result = [Return(expression.value)]
return result
if isinstance(expression, Literal) and node.type in [NodeType.IF, NodeType.IFLOOP]: if isinstance(expression, Literal) and node.type in [NodeType.IF, NodeType.IFLOOP]:
result = [Condition(Constant(expression.value))] result = [Condition(Constant(expression.value))]
return result return result
if isinstance(expression, Identifier) and node.type in [NodeType.IF, NodeType.IFLOOP]: if isinstance(expression, Identifier) and node.type in [NodeType.IF, NodeType.IFLOOP]:
result = [Condition(expression.value)] result = [Condition(expression.value)]
return result return result
visitor = ExpressionToSlithIR(expression, node) visitor = ExpressionToSlithIR(expression, node)
result = visitor.result() result = visitor.result()

@ -7,21 +7,27 @@ class Return(Operation):
Return Return
Only present as last operation in RETURN node Only present as last operation in RETURN node
""" """
def __init__(self, value): def __init__(self, values):
# Note: Can return None # Note: Can return None
# ex: return call() # ex: return call()
# where call() dont return # where call() dont return
assert is_valid_rvalue(value) or isinstance(value, TupleVariable) or value == None if not isinstance(values, list):
assert is_valid_rvalue(values) or isinstance(values, TupleVariable) or values == None
if not values is None:
values = [values]
else:
for value in values:
assert is_valid_rvalue(value) or isinstance(value, TupleVariable)
super(Return, self).__init__() super(Return, self).__init__()
self._value = value self._values = values
@property @property
def read(self): def read(self):
return [self.value] return self.values
@property @property
def value(self): def values(self):
return self._value return self._values
def __str__(self): def __str__(self):
return "RETURN {}".format(self.value) return "RETURN {}".format(','.join(['{}'.format(x) for x in self.values]))

@ -7,7 +7,7 @@ from slither.core.solidity_types.array_type import ArrayType
from slither.slithir.operations import (Assignment, Binary, BinaryType, Delete, from slither.slithir.operations import (Assignment, Binary, BinaryType, Delete,
Index, InitArray, InternalCall, Member, Index, InitArray, InternalCall, Member,
NewArray, NewContract, NewStructure, NewArray, NewContract, NewStructure,
TypeConversion, Unary, Unpack) TypeConversion, Unary, Unpack, Return)
from slither.slithir.tmp_operations.argument import Argument from slither.slithir.tmp_operations.argument import Argument
from slither.slithir.tmp_operations.tmp_call import TmpCall from slither.slithir.tmp_operations.tmp_call import TmpCall
from slither.slithir.tmp_operations.tmp_new_array import TmpNewArray from slither.slithir.tmp_operations.tmp_new_array import TmpNewArray
@ -62,10 +62,13 @@ def convert_assignment(left, right, t, return_type):
class ExpressionToSlithIR(ExpressionVisitor): class ExpressionToSlithIR(ExpressionVisitor):
def __init__(self, expression, node): def __init__(self, expression, node):
from slither.core.cfg.node import NodeType
self._expression = expression self._expression = expression
self._node = node self._node = node
self._result = [] self._result = []
self._visit_expression(self.expression) self._visit_expression(self.expression)
if node.type == NodeType.RETURN:
self._result.append(Return(get(self.expression)))
for ir in self._result: for ir in self._result:
ir.set_node(node) ir.set_node(node)

Loading…
Cancel
Save