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,
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.variables.variable import Variable
from slither.slithir.operations import (Assignment, Binary, BinaryType, Call,
@ -667,18 +667,15 @@ def convert_expression(expression, node):
# handle standlone expression
# such as return true;
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]:
result = [Condition(Constant(expression.value))]
return result
if isinstance(expression, Identifier) and node.type in [NodeType.IF, NodeType.IFLOOP]:
result = [Condition(expression.value)]
return result
visitor = ExpressionToSlithIR(expression, node)
result = visitor.result()

@ -7,21 +7,27 @@ class Return(Operation):
Return
Only present as last operation in RETURN node
"""
def __init__(self, value):
def __init__(self, values):
# Note: Can return None
# ex: return call()
# 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__()
self._value = value
self._values = values
@property
def read(self):
return [self.value]
return self.values
@property
def value(self):
return self._value
def values(self):
return self._values
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,
Index, InitArray, InternalCall, Member,
NewArray, NewContract, NewStructure,
TypeConversion, Unary, Unpack)
TypeConversion, Unary, Unpack, Return)
from slither.slithir.tmp_operations.argument import Argument
from slither.slithir.tmp_operations.tmp_call import TmpCall
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):
def __init__(self, expression, node):
from slither.core.cfg.node import NodeType
self._expression = expression
self._node = node
self._result = []
self._visit_expression(self.expression)
if node.type == NodeType.RETURN:
self._result.append(Return(get(self.expression)))
for ir in self._result:
ir.set_node(node)

Loading…
Cancel
Save