We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug]: constant folding is failing on negated negatives (array slicing?)
### What happened?

Slither fails to parse the constants in the below code, but it is considered valid solidity syntax.

### Can you share code with us to reproduce this bug?

https://github.com/ethereum/solidity/blob/develop/test/libsolidity/syntaxTests/constantEvaluator/unary_fine.sol
```
contract C {
    int8 constant a = -7;
    function f() public pure {
        uint[-a] memory x;
        x[0] = 2;
    }
}
```

### Version

0.8.2

### Relevant log output

```shell
Traceback (most recent call last):
  File "/Users/alpharush/solidity/test/libsolidity/syntaxTests/test.py", line 17, in <module>
    Slither(test, disallow_partial=True)
  File "/Users/alpharush/Desktop/slither/slither/slither.py", line 120, in __init__
    parser.parse_contracts()
  File "/Users/alpharush/Desktop/slither/slither/solc_parsing/slither_compilation_unit_solc.py", line 435, in parse_contracts
    self._analyze_third_part(contracts_to_be_analyzed, libraries)
  File "/Users/alpharush/Desktop/slither/slither/solc_parsing/slither_compilation_unit_solc.py", line 541, in _analyze_third_part
    self._analyze_variables_modifiers_functions(contract)
  File "/Users/alpharush/Desktop/slither/slither/solc_parsing/slither_compilation_unit_solc.py", line 614, in _analyze_variables_modifiers_functions
    contract.analyze_content_functions()
  File "/Users/alpharush/Desktop/slither/slither/solc_parsing/declarations/contract.py", line 378, in analyze_content_functions
    function_parser.analyze_content()
  File "/Users/alpharush/Desktop/slither/slither/solc_parsing/declarations/function.py", line 302, in analyze_content
    local_var_parser.analyze(self)
  File "/Users/alpharush/Desktop/slither/slither/solc_parsing/variables/variable_declaration.py", line 190, in analyze
    self._variable.type = parse_type(self._elem_to_parse, caller_context)
  File "/Users/alpharush/Desktop/slither/slither/solc_parsing/solidity_types/type_parsing.py", line 367, in parse_type
    return ArrayType(array_type, length)
  File "/Users/alpharush/Desktop/slither/slither/core/solidity_types/array_type.py", line 22, in __init__
    cf = ConstantFolding(length, "uint256")
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py", line 27, in __init__
    super().__init__(expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 30, in __init__
    self._visit_expression(self.expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 87, in _visit_expression
    self._visit_unary_operation(expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 158, in _visit_unary_operation
    self._visit_expression(expression.expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 95, in _visit_expression
    self._post_visit(expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 280, in _post_visit
    self._post_identifier(expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py", line 38, in _post_identifier
    cf = ConstantFolding(expr, self._type)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py", line 27, in __init__
    super().__init__(expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 30, in __init__
    self._visit_expression(self.expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 95, in _visit_expression
    self._post_visit(expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py", line 307, in _post_visit
    self._post_unary_operation(expression)
  File "/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py", line 68, in _post_unary_operation
    raise NotConstant
slither.visitors.expression.constants_folding.NotConstant
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `slither/visitors/expression/constants_folding.py`
Content:
```
1 from slither.core.expressions import BinaryOperationType, Literal
2 from slither.utils.integer_conversion import convert_string_to_int
3 from slither.visitors.expression.expression import ExpressionVisitor
4 
5 
6 class NotConstant(Exception):
7     pass
8 
9 
10 KEY = "ConstantFolding"
11 
12 
13 def get_val(expression):
14     val = expression.context[KEY]
15     # we delete the item to reduce memory use
16     del expression.context[KEY]
17     return val
18 
19 
20 def set_val(expression, val):
21     expression.context[KEY] = val
22 
23 
24 class ConstantFolding(ExpressionVisitor):
25     def __init__(self, expression, custom_type):
26         self._type = custom_type
27         super().__init__(expression)
28 
29     def result(self):
30         return Literal(int(get_val(self._expression)), self._type)
31 
32     def _post_identifier(self, expression):
33         if not expression.value.is_constant:
34             raise NotConstant
35         expr = expression.value.expression
36         # assumption that we won't have infinite loop
37         if not isinstance(expr, Literal):
38             cf = ConstantFolding(expr, self._type)
39             expr = cf.result()
40         set_val(expression, convert_string_to_int(expr.value))
41 
42     def _post_binary_operation(self, expression):
43         left = get_val(expression.expression_left)
44         right = get_val(expression.expression_right)
45         if expression.type == BinaryOperationType.POWER:
46             set_val(expression, left ** right)
47         elif expression.type == BinaryOperationType.MULTIPLICATION:
48             set_val(expression, left * right)
49         elif expression.type == BinaryOperationType.DIVISION:
50             set_val(expression, left / right)
51         elif expression.type == BinaryOperationType.MODULO:
52             set_val(expression, left % right)
53         elif expression.type == BinaryOperationType.ADDITION:
54             set_val(expression, left + right)
55         elif expression.type == BinaryOperationType.SUBTRACTION:
56             if (left - right) < 0:
57                 # Could trigger underflow
58                 raise NotConstant
59             set_val(expression, left - right)
60         elif expression.type == BinaryOperationType.LEFT_SHIFT:
61             set_val(expression, left << right)
62         elif expression.type == BinaryOperationType.RIGHT_SHIFT:
63             set_val(expression, left >> right)
64         else:
65             raise NotConstant
66 
67     def _post_unary_operation(self, expression):
68         raise NotConstant
69 
70     def _post_literal(self, expression):
71         if expression.value.isdigit():
72             set_val(expression, int(expression.value))
73         else:
74             raise NotConstant
75 
76     def _post_assignement_operation(self, expression):
77         raise NotConstant
78 
79     def _post_call_expression(self, expression):
80         raise NotConstant
81 
82     def _post_conditional_expression(self, expression):
83         raise NotConstant
84 
85     def _post_elementary_type_name_expression(self, expression):
86         raise NotConstant
87 
88     def _post_index_access(self, expression):
89         raise NotConstant
90 
91     def _post_member_access(self, expression):
92         raise NotConstant
93 
94     def _post_new_array(self, expression):
95         raise NotConstant
96 
97     def _post_new_contract(self, expression):
98         raise NotConstant
99 
100     def _post_new_elementary_type(self, expression):
101         raise NotConstant
102 
103     def _post_tuple_expression(self, expression):
104         if expression.expressions:
105             if len(expression.expressions) == 1:
106                 cf = ConstantFolding(expression.expressions[0], self._type)
107                 expr = cf.result()
108                 assert isinstance(expr, Literal)
109                 set_val(expression, int(expr.value))
110                 return
111         raise NotConstant
112 
113     def _post_type_conversion(self, expression):
114         raise NotConstant
115
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py
--- a/slither/visitors/expression/constants_folding.py
+++ b/slither/visitors/expression/constants_folding.py
@@ -1,4 +1,4 @@
-from slither.core.expressions import BinaryOperationType, Literal
+from slither.core.expressions import BinaryOperationType, Literal, UnaryOperationType
 from slither.utils.integer_conversion import convert_string_to_int
 from slither.visitors.expression.expression import ExpressionVisitor
 
@@ -65,7 +65,16 @@
             raise NotConstant
 
     def _post_unary_operation(self, expression):
-        raise NotConstant
+        # Case of uint a = -7; uint[-a] arr;
+        if expression.type == UnaryOperationType.MINUS_PRE:
+            expr = expression.expression
+            if not isinstance(expr, Literal):
+                cf = ConstantFolding(expr, self._type)
+                expr = cf.result()
+            assert isinstance(expr, Literal)
+            set_val(expression, int(expr.value))
+        else:
+            raise NotConstant
 
     def _post_literal(self, expression):
         if expression.value.isdigit():

{"golden_diff": "diff --git a/slither/visitors/expression/constants_folding.py b/slither/visitors/expression/constants_folding.py\n--- a/slither/visitors/expression/constants_folding.py\n+++ b/slither/visitors/expression/constants_folding.py\n@@ -1,4 +1,4 @@\n-from slither.core.expressions import BinaryOperationType, Literal\n+from slither.core.expressions import BinaryOperationType, Literal, UnaryOperationType\n from slither.utils.integer_conversion import convert_string_to_int\n from slither.visitors.expression.expression import ExpressionVisitor\n \n@@ -65,7 +65,16 @@\n             raise NotConstant\n \n     def _post_unary_operation(self, expression):\n-        raise NotConstant\n+        # Case of uint a = -7; uint[-a] arr;\n+        if expression.type == UnaryOperationType.MINUS_PRE:\n+            expr = expression.expression\n+            if not isinstance(expr, Literal):\n+                cf = ConstantFolding(expr, self._type)\n+                expr = cf.result()\n+            assert isinstance(expr, Literal)\n+            set_val(expression, int(expr.value))\n+        else:\n+            raise NotConstant\n \n     def _post_literal(self, expression):\n         if expression.value.isdigit():\n", "issue": "[Bug]: constant folding is failing on negated negatives (array slicing?)\n### What happened?\r\n\r\nSlither fails to parse the constants in the below code, but it is considered valid solidity syntax.\r\n\r\n### Can you share code with us to reproduce this bug?\r\n\r\nhttps://github.com/ethereum/solidity/blob/develop/test/libsolidity/syntaxTests/constantEvaluator/unary_fine.sol\r\n```\r\ncontract C {\r\n    int8 constant a = -7;\r\n    function f() public pure {\r\n        uint[-a] memory x;\r\n        x[0] = 2;\r\n    }\r\n}\r\n```\r\n\r\n### Version\r\n\r\n0.8.2\r\n\r\n### Relevant log output\r\n\r\n```shell\r\nTraceback (most recent call last):\r\n  File \"/Users/alpharush/solidity/test/libsolidity/syntaxTests/test.py\", line 17, in <module>\r\n    Slither(test, disallow_partial=True)\r\n  File \"/Users/alpharush/Desktop/slither/slither/slither.py\", line 120, in __init__\r\n    parser.parse_contracts()\r\n  File \"/Users/alpharush/Desktop/slither/slither/solc_parsing/slither_compilation_unit_solc.py\", line 435, in parse_contracts\r\n    self._analyze_third_part(contracts_to_be_analyzed, libraries)\r\n  File \"/Users/alpharush/Desktop/slither/slither/solc_parsing/slither_compilation_unit_solc.py\", line 541, in _analyze_third_part\r\n    self._analyze_variables_modifiers_functions(contract)\r\n  File \"/Users/alpharush/Desktop/slither/slither/solc_parsing/slither_compilation_unit_solc.py\", line 614, in _analyze_variables_modifiers_functions\r\n    contract.analyze_content_functions()\r\n  File \"/Users/alpharush/Desktop/slither/slither/solc_parsing/declarations/contract.py\", line 378, in analyze_content_functions\r\n    function_parser.analyze_content()\r\n  File \"/Users/alpharush/Desktop/slither/slither/solc_parsing/declarations/function.py\", line 302, in analyze_content\r\n    local_var_parser.analyze(self)\r\n  File \"/Users/alpharush/Desktop/slither/slither/solc_parsing/variables/variable_declaration.py\", line 190, in analyze\r\n    self._variable.type = parse_type(self._elem_to_parse, caller_context)\r\n  File \"/Users/alpharush/Desktop/slither/slither/solc_parsing/solidity_types/type_parsing.py\", line 367, in parse_type\r\n    return ArrayType(array_type, length)\r\n  File \"/Users/alpharush/Desktop/slither/slither/core/solidity_types/array_type.py\", line 22, in __init__\r\n    cf = ConstantFolding(length, \"uint256\")\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py\", line 27, in __init__\r\n    super().__init__(expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 30, in __init__\r\n    self._visit_expression(self.expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 87, in _visit_expression\r\n    self._visit_unary_operation(expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 158, in _visit_unary_operation\r\n    self._visit_expression(expression.expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 95, in _visit_expression\r\n    self._post_visit(expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 280, in _post_visit\r\n    self._post_identifier(expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py\", line 38, in _post_identifier\r\n    cf = ConstantFolding(expr, self._type)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py\", line 27, in __init__\r\n    super().__init__(expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 30, in __init__\r\n    self._visit_expression(self.expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 95, in _visit_expression\r\n    self._post_visit(expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/expression.py\", line 307, in _post_visit\r\n    self._post_unary_operation(expression)\r\n  File \"/Users/alpharush/Desktop/slither/slither/visitors/expression/constants_folding.py\", line 68, in _post_unary_operation\r\n    raise NotConstant\r\nslither.visitors.expression.constants_folding.NotConstant\r\n```\r\n\n", "before_files": [{"content": "from slither.core.expressions import BinaryOperationType, Literal\nfrom slither.utils.integer_conversion import convert_string_to_int\nfrom slither.visitors.expression.expression import ExpressionVisitor\n\n\nclass NotConstant(Exception):\n    pass\n\n\nKEY = \"ConstantFolding\"\n\n\ndef get_val(expression):\n    val = expression.context[KEY]\n    # we delete the item to reduce memory use\n    del expression.context[KEY]\n    return val\n\n\ndef set_val(expression, val):\n    expression.context[KEY] = val\n\n\nclass ConstantFolding(ExpressionVisitor):\n    def __init__(self, expression, custom_type):\n        self._type = custom_type\n        super().__init__(expression)\n\n    def result(self):\n        return Literal(int(get_val(self._expression)), self._type)\n\n    def _post_identifier(self, expression):\n        if not expression.value.is_constant:\n            raise NotConstant\n        expr = expression.value.expression\n        # assumption that we won't have infinite loop\n        if not isinstance(expr, Literal):\n            cf = ConstantFolding(expr, self._type)\n            expr = cf.result()\n        set_val(expression, convert_string_to_int(expr.value))\n\n    def _post_binary_operation(self, expression):\n        left = get_val(expression.expression_left)\n        right = get_val(expression.expression_right)\n        if expression.type == BinaryOperationType.POWER:\n            set_val(expression, left ** right)\n        elif expression.type == BinaryOperationType.MULTIPLICATION:\n            set_val(expression, left * right)\n        elif expression.type == BinaryOperationType.DIVISION:\n            set_val(expression, left / right)\n        elif expression.type == BinaryOperationType.MODULO:\n            set_val(expression, left % right)\n        elif expression.type == BinaryOperationType.ADDITION:\n            set_val(expression, left + right)\n        elif expression.type == BinaryOperationType.SUBTRACTION:\n            if (left - right) < 0:\n                # Could trigger underflow\n                raise NotConstant\n            set_val(expression, left - right)\n        elif expression.type == BinaryOperationType.LEFT_SHIFT:\n            set_val(expression, left << right)\n        elif expression.type == BinaryOperationType.RIGHT_SHIFT:\n            set_val(expression, left >> right)\n        else:\n            raise NotConstant\n\n    def _post_unary_operation(self, expression):\n        raise NotConstant\n\n    def _post_literal(self, expression):\n        if expression.value.isdigit():\n            set_val(expression, int(expression.value))\n        else:\n            raise NotConstant\n\n    def _post_assignement_operation(self, expression):\n        raise NotConstant\n\n    def _post_call_expression(self, expression):\n        raise NotConstant\n\n    def _post_conditional_expression(self, expression):\n        raise NotConstant\n\n    def _post_elementary_type_name_expression(self, expression):\n        raise NotConstant\n\n    def _post_index_access(self, expression):\n        raise NotConstant\n\n    def _post_member_access(self, expression):\n        raise NotConstant\n\n    def _post_new_array(self, expression):\n        raise NotConstant\n\n    def _post_new_contract(self, expression):\n        raise NotConstant\n\n    def _post_new_elementary_type(self, expression):\n        raise NotConstant\n\n    def _post_tuple_expression(self, expression):\n        if expression.expressions:\n            if len(expression.expressions) == 1:\n                cf = ConstantFolding(expression.expressions[0], self._type)\n                expr = cf.result()\n                assert isinstance(expr, Literal)\n                set_val(expression, int(expr.value))\n                return\n        raise NotConstant\n\n    def _post_type_conversion(self, expression):\n        raise NotConstant\n", "path": "slither/visitors/expression/constants_folding.py"}], "after_files": [{"content": "from slither.core.expressions import BinaryOperationType, Literal, UnaryOperationType\nfrom slither.utils.integer_conversion import convert_string_to_int\nfrom slither.visitors.expression.expression import ExpressionVisitor\n\n\nclass NotConstant(Exception):\n    pass\n\n\nKEY = \"ConstantFolding\"\n\n\ndef get_val(expression):\n    val = expression.context[KEY]\n    # we delete the item to reduce memory use\n    del expression.context[KEY]\n    return val\n\n\ndef set_val(expression, val):\n    expression.context[KEY] = val\n\n\nclass ConstantFolding(ExpressionVisitor):\n    def __init__(self, expression, custom_type):\n        self._type = custom_type\n        super().__init__(expression)\n\n    def result(self):\n        return Literal(int(get_val(self._expression)), self._type)\n\n    def _post_identifier(self, expression):\n        if not expression.value.is_constant:\n            raise NotConstant\n        expr = expression.value.expression\n        # assumption that we won't have infinite loop\n        if not isinstance(expr, Literal):\n            cf = ConstantFolding(expr, self._type)\n            expr = cf.result()\n        set_val(expression, convert_string_to_int(expr.value))\n\n    def _post_binary_operation(self, expression):\n        left = get_val(expression.expression_left)\n        right = get_val(expression.expression_right)\n        if expression.type == BinaryOperationType.POWER:\n            set_val(expression, left ** right)\n        elif expression.type == BinaryOperationType.MULTIPLICATION:\n            set_val(expression, left * right)\n        elif expression.type == BinaryOperationType.DIVISION:\n            set_val(expression, left / right)\n        elif expression.type == BinaryOperationType.MODULO:\n            set_val(expression, left % right)\n        elif expression.type == BinaryOperationType.ADDITION:\n            set_val(expression, left + right)\n        elif expression.type == BinaryOperationType.SUBTRACTION:\n            if (left - right) < 0:\n                # Could trigger underflow\n                raise NotConstant\n            set_val(expression, left - right)\n        elif expression.type == BinaryOperationType.LEFT_SHIFT:\n            set_val(expression, left << right)\n        elif expression.type == BinaryOperationType.RIGHT_SHIFT:\n            set_val(expression, left >> right)\n        else:\n            raise NotConstant\n\n    def _post_unary_operation(self, expression):\n        # Case of uint a = -7; uint[-a] arr;\n        if expression.type == UnaryOperationType.MINUS_PRE:\n            expr = expression.expression\n            if not isinstance(expr, Literal):\n                cf = ConstantFolding(expr, self._type)\n                expr = cf.result()\n            assert isinstance(expr, Literal)\n            set_val(expression, int(expr.value))\n        else:\n            raise NotConstant\n\n    def _post_literal(self, expression):\n        if expression.value.isdigit():\n            set_val(expression, int(expression.value))\n        else:\n            raise NotConstant\n\n    def _post_assignement_operation(self, expression):\n        raise NotConstant\n\n    def _post_call_expression(self, expression):\n        raise NotConstant\n\n    def _post_conditional_expression(self, expression):\n        raise NotConstant\n\n    def _post_elementary_type_name_expression(self, expression):\n        raise NotConstant\n\n    def _post_index_access(self, expression):\n        raise NotConstant\n\n    def _post_member_access(self, expression):\n        raise NotConstant\n\n    def _post_new_array(self, expression):\n        raise NotConstant\n\n    def _post_new_contract(self, expression):\n        raise NotConstant\n\n    def _post_new_elementary_type(self, expression):\n        raise NotConstant\n\n    def _post_tuple_expression(self, expression):\n        if expression.expressions:\n            if len(expression.expressions) == 1:\n                cf = ConstantFolding(expression.expressions[0], self._type)\n                expr = cf.result()\n                assert isinstance(expr, Literal)\n                set_val(expression, int(expr.value))\n                return\n        raise NotConstant\n\n    def _post_type_conversion(self, expression):\n        raise NotConstant\n", "path": "slither/visitors/expression/constants_folding.py"}]}