Repository: crytic/slither

Issue:
AssertionError parsing function-type return values
The following contract causes an assertion error:
```
contract FunctionReturningFunction {
    function f() public { }

    function g() internal returns (function() internal) {
        return f;
    }
}
```

Output:
```
ERROR:root:Error in .\function_returning_function.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 105, in __init__
    r = Return(get(self.expression))
  File "c:\users\x\documents\github\slither\slither\slithir\operations\return_operation.py", line 18, in __init__
    assert is_valid_rvalue(values) or isinstance(values, TupleVariable) or values is None
AssertionError
```
AssertionError parsing function-type return values
The following contract causes an assertion error:
```
contract FunctionReturningFunction {
    function f() public { }

    function g() internal returns (function() internal) {
        return f;
    }
}
```

Output:
```
ERROR:root:Error in .\function_returning_function.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 105, in __init__
    r = Return(get(self.expression))
  File "c:\users\x\documents\github\slither\slither\slithir\operations\return_operation.py", line 18, in __init__
    assert is_valid_rvalue(values) or isinstance(values, TupleVariable) or values is None
AssertionError
```


Discussion:

Resolving patch:
diff --git a/slither/slithir/operations/return_operation.py b/slither/slithir/operations/return_operation.py
--- a/slither/slithir/operations/return_operation.py
+++ b/slither/slithir/operations/return_operation.py
@@ -1,3 +1,4 @@
+from slither.core.declarations import Function
 from slither.slithir.operations.operation import Operation
 
 from slither.slithir.variables.tuple import TupleVariable
@@ -15,7 +16,7 @@ def __init__(self, values):
         # ex: return call()
         # where call() dont return
         if not isinstance(values, list):
-            assert is_valid_rvalue(values) or isinstance(values, TupleVariable) or values is None
+            assert is_valid_rvalue(values) or isinstance(values, (TupleVariable, Function)) or values is None
             if values is None:
                 values = []
             else:
@@ -34,7 +35,7 @@ def _valid_value(self, value):
         if isinstance(value, list):
             assert all(self._valid_value(v) for v in value)
         else:
-            assert is_valid_rvalue(value) or isinstance(value, TupleVariable)
+            assert is_valid_rvalue(value) or isinstance(value, (TupleVariable, Function))
         return True
 
     @property


Test patch: