Repository: crytic/slither

Issue:
AssertionError when comparing two functions with Binary operation
The following contract causes an assertion error:
```
contract FunctionComparisonTest {
    function f() public returns (bool) {
        return f == f;
    }
}
```

Output:
```
ERROR:root:Error in .\function_comparison.sol
ERROR:root:Traceback (most recent call last):
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 610, in main_impl
    (slither_instances, results_detectors, results_printers, number_contracts) = process_all(filename, args,
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 67, in process_all
    (slither, current_results_detectors, current_results_printers, current_analyzed_count) = process_single(
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 53, in process_single
    slither = Slither(target,
  File "c:\users\x\documents\github\slither\slither\slither.py", line 86, in __init__
    self._parser.analyze_contracts()
  File "c:\users\x\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 345, in analyze_contracts
    self._convert_to_slithir()
  File "c:\users\x\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 489, in _convert_to_slithir
    func.generate_slithir_and_analyze()
  File "c:\users\x\documents\github\slither\slither\core\declarations\function.py", line 1652, in generate_slithir_and_analyze
    node.slithir_generation()
  File "c:\users\x\documents\github\slither\slither\core\cfg\node.py", line 702, in slithir_generation
    self._irs = convert_expression(expression, self)
  File "c:\users\x\documents\github\slither\slither\slithir\convert.py", line 64, in convert_expression
    visitor = ExpressionToSlithIR(expression, node)
  File "c:\users\x\documents\github\slither\slither\visitors\slithir\expression_to_slithir.py", line 103, in __init__
    self._visit_expression(self.expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 95, in _visit_expression
    self._post_visit(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 268, in _post_visit
    self._post_binary_operation(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\slithir\expression_to_slithir.py", line 192, in _post_binary_operation
    operation = Binary(val, left, right, _binary_to_binary[expression.type])
  File "c:\users\x\documents\github\slither\slither\slithir\operations\binary.py", line 133, in __init__
    assert is_valid_rvalue(left_variable)
AssertionError
```


Discussion:

Resolving patch:
diff --git a/slither/slithir/operations/binary.py b/slither/slithir/operations/binary.py
--- a/slither/slithir/operations/binary.py
+++ b/slither/slithir/operations/binary.py
@@ -1,6 +1,7 @@
 import logging
 from enum import Enum
 
+from slither.core.declarations import Function
 from slither.core.solidity_types import ElementaryType
 from slither.slithir.exceptions import SlithIRError
 from slither.slithir.operations.lvalue import OperationWithLValue
@@ -131,8 +132,8 @@ def __str__(self):  # pylint: disable=too-many-branches
 
 class Binary(OperationWithLValue):
     def __init__(self, result, left_variable, right_variable, operation_type):
-        assert is_valid_rvalue(left_variable)
-        assert is_valid_rvalue(right_variable)
+        assert is_valid_rvalue(left_variable) or isinstance(left_variable, Function)
+        assert is_valid_rvalue(right_variable) or isinstance(right_variable, Function)
         assert is_valid_lvalue(result)
         assert isinstance(operation_type, BinaryType)
         super().__init__()


Test patch: