From 66ae66b09c3300df2b306987b678cb209621b0f2 Mon Sep 17 00:00:00 2001 From: samczsun Date: Tue, 23 Jun 2020 17:52:42 -0400 Subject: [PATCH] translate signed operations --- slither/slithir/operations/binary.py | 26 ------------ .../visitors/slithir/expression_to_slithir.py | 40 +++++++++++++++---- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/slither/slithir/operations/binary.py b/slither/slithir/operations/binary.py index fce83aa6d..cd886197f 100644 --- a/slither/slithir/operations/binary.py +++ b/slither/slithir/operations/binary.py @@ -31,12 +31,6 @@ class BinaryType(Enum): ANDAND = 17 # && OROR = 18 # || - DIVISION_SIGNED = 19 - MODULO_SIGNED = 20 - LESS_SIGNED = 21 - GREATER_SIGNED = 22 - RIGHT_SHIFT_ARITHMETIC = 23 - @staticmethod def return_bool(operation_type): return operation_type in [BinaryType.OROR, @@ -88,16 +82,6 @@ class BinaryType(Enum): return BinaryType.ANDAND if operation_type == '||': return BinaryType.OROR - if operation_type == "/'": - return BinaryType.DIVISION_SIGNED - if operation_type == "%'": - return BinaryType.MODULO_SIGNED - if operation_type == "<'": - return BinaryType.LESS_SIGNED - if operation_type == ">'": - return BinaryType.GREATER_SIGNED - if operation_type == ">>'": - return BinaryType.RIGHT_SHIFT_ARITHMETIC raise SlithIRError('get_type: Unknown operation type {})'.format(operation_type)) @@ -140,16 +124,6 @@ class BinaryType(Enum): return "&&" if self == BinaryType.OROR: return "||" - if self == BinaryType.DIVISION_SIGNED: - return "/'" - if self == BinaryType.MODULO_SIGNED: - return "%'" - if self == BinaryType.LESS_SIGNED: - return "<'" - if self == BinaryType.GREATER_SIGNED: - return ">'" - if self == BinaryType.RIGHT_SHIFT_ARITHMETIC: - return ">>'" raise SlithIRError("str: Unknown operation type {} {})".format(self, type(self))) diff --git a/slither/visitors/slithir/expression_to_slithir.py b/slither/visitors/slithir/expression_to_slithir.py index 1fea831a9..99d41d3e5 100644 --- a/slither/visitors/slithir/expression_to_slithir.py +++ b/slither/visitors/slithir/expression_to_slithir.py @@ -55,13 +55,17 @@ _binary_to_binary = { BinaryOperationType.NOT_EQUAL: BinaryType.NOT_EQUAL, BinaryOperationType.ANDAND: BinaryType.ANDAND, BinaryOperationType.OROR: BinaryType.OROR, - BinaryOperationType.DIVISION_SIGNED: BinaryType.DIVISION_SIGNED, - BinaryOperationType.MODULO_SIGNED: BinaryType.MODULO_SIGNED, - BinaryOperationType.LESS_SIGNED: BinaryType.LESS_SIGNED, - BinaryOperationType.GREATER_SIGNED: BinaryType.GREATER_SIGNED, - BinaryOperationType.RIGHT_SHIFT_ARITHMETIC: BinaryType.RIGHT_SHIFT_ARITHMETIC, } +_signed_to_unsigned = { + BinaryOperationType.DIVISION_SIGNED: BinaryType.DIVISION, + BinaryOperationType.MODULO_SIGNED: BinaryType.MODULO, + BinaryOperationType.LESS_SIGNED: BinaryType.LESS, + BinaryOperationType.GREATER_SIGNED: BinaryType.GREATER, + BinaryOperationType.RIGHT_SHIFT_ARITHMETIC: BinaryType.RIGHT_SHIFT, +} + + def convert_assignment(left, right, t, return_type): if t == AssignmentOperationType.ASSIGN: return Assignment(left, right, return_type) @@ -147,9 +151,29 @@ class ExpressionToSlithIR(ExpressionVisitor): right = get(expression.expression_right) val = TemporaryVariable(self._node) - operation = Binary(val, left, right, _binary_to_binary[expression.type]) - operation.set_expression(expression) - self._result.append(operation) + if expression.type in _signed_to_unsigned: + new_left = TemporaryVariable(self._node) + conv_left = TypeConversion(new_left, left, ElementaryType('int256')) + conv_left.set_expression(expression) + self._result.append(conv_left) + + if expression.type != BinaryOperationType.RIGHT_SHIFT_ARITHMETIC: + new_right = TemporaryVariable(self._node) + conv_right = TypeConversion(new_right, right, ElementaryType('int256')) + conv_right.set_expression(expression) + self._result.append(conv_right) + else: + new_right = right + + operation = Binary(val, new_left, new_right, _signed_to_unsigned[expression.type]) + operation.set_expression(expression) + val.set_type(ElementaryType('uint256')) # overwrite the result from Binary() for now + self._result.append(operation) + else: + operation = Binary(val, left, right, _binary_to_binary[expression.type]) + operation.set_expression(expression) + self._result.append(operation) + set_val(expression, val) def _post_call_expression(self, expression):