Skip to content

Commit 571a849

Browse files
committed
Add scope information in slithIR CFG
The main usage in the short term is to allow unchecked block In the long term it will allow better handling of variables usage
1 parent 9533947 commit 571a849

File tree

133 files changed

+238
-110
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+238
-110
lines changed

slither/core/cfg/node.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
LibraryCallType,
5555
LowLevelCallType,
5656
)
57+
from slither.core.cfg.scope import Scope
5758

5859

5960
# pylint: disable=too-many-lines,too-many-branches,too-many-instance-attributes
@@ -152,7 +153,7 @@ class Node(SourceMapping, ChildFunction): # pylint: disable=too-many-public-met
152153
153154
"""
154155

155-
def __init__(self, node_type: NodeType, node_id: int):
156+
def __init__(self, node_type: NodeType, node_id: int, scope: Union["Scope", "Function"]):
156157
super().__init__()
157158
self._node_type = node_type
158159

@@ -220,6 +221,8 @@ def __init__(self, node_type: NodeType, node_id: int):
220221

221222
self._asm_source_code: Optional[Union[str, Dict]] = None
222223

224+
self.scope = scope
225+
223226
###################################################################################
224227
###################################################################################
225228
# region General's properties

slither/core/cfg/scope.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from typing import List, TYPE_CHECKING, Union
2+
3+
if TYPE_CHECKING:
4+
from slither.core.cfg.node import Node
5+
from slither.core.declarations.function import Function
6+
7+
8+
class Scope:
9+
10+
def __init__(self, is_checked:bool, is_yul: bool, scope: Union["Scope", "Function"]):
11+
self.nodes: List[Node] = []
12+
self.is_checked = is_checked
13+
self.is_yul = is_yul
14+
self.father = scope

slither/core/declarations/contract.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from crytic_compile.platform import Type as PlatformType
99

10+
from slither.core.cfg.scope import Scope
1011
from slither.core.solidity_types.type import Type
1112
from slither.core.source_mapping.source_mapping import SourceMapping
1213

@@ -1114,12 +1115,12 @@ def add_constructor_variables(self):
11141115
constructor_variable.set_offset(self.source_mapping, self.compilation_unit)
11151116
self._functions[constructor_variable.canonical_name] = constructor_variable
11161117

1117-
prev_node = self._create_node(constructor_variable, 0, variable_candidate)
1118+
prev_node = self._create_node(constructor_variable, 0, variable_candidate, constructor_variable)
11181119
variable_candidate.node_initialization = prev_node
11191120
counter = 1
11201121
for v in self.state_variables[idx + 1 :]:
11211122
if v.expression and not v.is_constant:
1122-
next_node = self._create_node(constructor_variable, counter, v)
1123+
next_node = self._create_node(constructor_variable, counter, v, prev_node.scope)
11231124
v.node_initialization = next_node
11241125
prev_node.add_son(next_node)
11251126
next_node.add_father(prev_node)
@@ -1142,12 +1143,12 @@ def add_constructor_variables(self):
11421143
constructor_variable.set_offset(self.source_mapping, self.compilation_unit)
11431144
self._functions[constructor_variable.canonical_name] = constructor_variable
11441145

1145-
prev_node = self._create_node(constructor_variable, 0, variable_candidate)
1146+
prev_node = self._create_node(constructor_variable, 0, variable_candidate, constructor_variable)
11461147
variable_candidate.node_initialization = prev_node
11471148
counter = 1
11481149
for v in self.state_variables[idx + 1 :]:
11491150
if v.expression and v.is_constant:
1150-
next_node = self._create_node(constructor_variable, counter, v)
1151+
next_node = self._create_node(constructor_variable, counter, v, prev_node.scope)
11511152
v.node_initialization = next_node
11521153
prev_node.add_son(next_node)
11531154
next_node.add_father(prev_node)
@@ -1156,7 +1157,7 @@ def add_constructor_variables(self):
11561157

11571158
break
11581159

1159-
def _create_node(self, func: Function, counter: int, variable: "Variable"):
1160+
def _create_node(self, func: Function, counter: int, variable: "Variable", scope: Union[Scope, Function]):
11601161
from slither.core.cfg.node import Node, NodeType
11611162
from slither.core.expressions import (
11621163
AssignmentOperationType,
@@ -1165,7 +1166,7 @@ def _create_node(self, func: Function, counter: int, variable: "Variable"):
11651166
)
11661167

11671168
# Function uses to create node for state variable declaration statements
1168-
node = Node(NodeType.OTHER_ENTRYPOINT, counter)
1169+
node = Node(NodeType.OTHER_ENTRYPOINT, counter, scope)
11691170
node.set_offset(variable.source_mapping, self.compilation_unit)
11701171
node.set_function(func)
11711172
func.add_node(node)

slither/core/declarations/function.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from itertools import groupby
99
from typing import Dict, TYPE_CHECKING, List, Optional, Set, Union, Callable, Tuple
1010

11+
from slither.core.cfg.scope import Scope
1112
from slither.core.declarations.solidity_variables import (
1213
SolidityFunction,
1314
SolidityVariable,
@@ -313,13 +314,16 @@ def can_send_eth(self) -> bool:
313314
return True
314315
return self._can_send_eth
315316

316-
# @property
317-
# def slither(self) -> "SlitherCore":
318-
# return self._slither
319-
#
320-
# @slither.setter
321-
# def slither(self, sl: "SlitherCore"):
322-
# self._slither = sl
317+
@property
318+
def is_checked(self) -> bool:
319+
"""
320+
Return true if the overflow are enabled by default
321+
322+
323+
:return:
324+
"""
325+
326+
return self.compilation_unit.solc_version >= "0.8.0"
323327

324328
# endregion
325329
###################################################################################
@@ -1527,10 +1531,10 @@ def _analyze_calls(self):
15271531
###################################################################################
15281532
###################################################################################
15291533

1530-
def new_node(self, node_type: "NodeType", src: Union[str, Dict]) -> "Node":
1534+
def new_node(self, node_type: "NodeType", src: Union[str, Dict], scope: Union[Scope, "Function"]) -> "Node":
15311535
from slither.core.cfg.node import Node
15321536

1533-
node = Node(node_type, self._counter_nodes)
1537+
node = Node(node_type, self._counter_nodes, scope)
15341538
node.set_offset(src, self.compilation_unit)
15351539
self._counter_nodes += 1
15361540
node.set_function(self)

slither/slithir/operations/binary.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def __str__(self): # pylint: disable=too-many-branches
131131

132132

133133
class Binary(OperationWithLValue):
134-
def __init__(self, result, left_variable, right_variable, operation_type):
134+
def __init__(self, result, left_variable, right_variable, operation_type: BinaryType, is_checked: bool=False):
135135
assert is_valid_rvalue(left_variable) or isinstance(left_variable, Function)
136136
assert is_valid_rvalue(right_variable) or isinstance(right_variable, Function)
137137
assert is_valid_lvalue(result)
@@ -144,6 +144,7 @@ def __init__(self, result, left_variable, right_variable, operation_type):
144144
result.set_type(ElementaryType("bool"))
145145
else:
146146
result.set_type(left_variable.type)
147+
self.is_checked = is_checked
147148

148149
@property
149150
def read(self):

0 commit comments

Comments
 (0)