angr 9.2.102__py3-none-manylinux2014_x86_64.whl → 9.2.103__py3-none-manylinux2014_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of angr might be problematic. Click here for more details.

Files changed (239) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/analysis.py +7 -6
  3. angr/analyses/calling_convention.py +33 -35
  4. angr/analyses/cdg.py +2 -4
  5. angr/analyses/cfg/cfb.py +4 -3
  6. angr/analyses/cfg/cfg_base.py +14 -14
  7. angr/analyses/cfg/cfg_emulated.py +3 -4
  8. angr/analyses/cfg/cfg_fast.py +46 -46
  9. angr/analyses/cfg/cfg_fast_soot.py +1 -2
  10. angr/analyses/cfg/cfg_job_base.py +2 -2
  11. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +14 -13
  12. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +5 -5
  13. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +3 -3
  14. angr/analyses/complete_calling_conventions.py +13 -12
  15. angr/analyses/data_dep/data_dependency_analysis.py +24 -24
  16. angr/analyses/data_dep/dep_nodes.py +3 -3
  17. angr/analyses/ddg.py +1 -2
  18. angr/analyses/decompiler/ail_simplifier.py +35 -34
  19. angr/analyses/decompiler/block_io_finder.py +20 -20
  20. angr/analyses/decompiler/block_similarity.py +4 -6
  21. angr/analyses/decompiler/block_simplifier.py +17 -16
  22. angr/analyses/decompiler/callsite_maker.py +25 -10
  23. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -3
  24. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +2 -4
  25. angr/analyses/decompiler/clinic.py +250 -45
  26. angr/analyses/decompiler/condition_processor.py +15 -8
  27. angr/analyses/decompiler/decompilation_cache.py +7 -7
  28. angr/analyses/decompiler/decompilation_options.py +4 -4
  29. angr/analyses/decompiler/decompiler.py +19 -15
  30. angr/analyses/decompiler/expression_counters.py +10 -9
  31. angr/analyses/decompiler/goto_manager.py +2 -4
  32. angr/analyses/decompiler/graph_region.py +9 -9
  33. angr/analyses/decompiler/jump_target_collector.py +1 -2
  34. angr/analyses/decompiler/optimization_passes/__init__.py +4 -3
  35. angr/analyses/decompiler/optimization_passes/code_motion.py +5 -6
  36. angr/analyses/decompiler/optimization_passes/const_derefs.py +4 -4
  37. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +73 -0
  38. angr/analyses/decompiler/optimization_passes/engine_base.py +25 -3
  39. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +6 -5
  40. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +2 -2
  41. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +3 -0
  42. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +2 -2
  43. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +17 -17
  44. angr/analyses/decompiler/optimization_passes/optimization_pass.py +12 -13
  45. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +25 -21
  46. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +3 -3
  47. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +1 -2
  48. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +7 -7
  49. angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +18 -0
  50. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +2 -3
  51. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +1 -2
  52. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +2 -2
  53. angr/analyses/decompiler/peephole_optimizations/__init__.py +4 -3
  54. angr/analyses/decompiler/peephole_optimizations/base.py +13 -15
  55. angr/analyses/decompiler/peephole_optimizations/bswap.py +1 -3
  56. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +72 -0
  57. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +1 -2
  58. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +1 -1
  59. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +5 -10
  60. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +3 -4
  61. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +7 -10
  62. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +2 -3
  63. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +1 -2
  64. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +4 -4
  65. angr/analyses/decompiler/redundant_label_remover.py +4 -5
  66. angr/analyses/decompiler/region_identifier.py +4 -5
  67. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +1 -2
  68. angr/analyses/decompiler/region_simplifiers/expr_folding.py +19 -20
  69. angr/analyses/decompiler/region_simplifiers/goto.py +2 -3
  70. angr/analyses/decompiler/region_simplifiers/loop.py +1 -2
  71. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -2
  72. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +1 -3
  73. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +19 -19
  74. angr/analyses/decompiler/return_maker.py +1 -2
  75. angr/analyses/decompiler/structured_codegen/base.py +5 -6
  76. angr/analyses/decompiler/structured_codegen/c.py +39 -38
  77. angr/analyses/decompiler/structuring/__init__.py +1 -1
  78. angr/analyses/decompiler/structuring/dream.py +17 -16
  79. angr/analyses/decompiler/structuring/phoenix.py +45 -46
  80. angr/analyses/decompiler/structuring/recursive_structurer.py +4 -4
  81. angr/analyses/decompiler/structuring/structurer_base.py +16 -15
  82. angr/analyses/decompiler/structuring/structurer_nodes.py +10 -9
  83. angr/analyses/decompiler/utils.py +17 -16
  84. angr/analyses/disassembly.py +7 -6
  85. angr/analyses/flirt.py +9 -9
  86. angr/analyses/forward_analysis/forward_analysis.py +15 -14
  87. angr/analyses/forward_analysis/visitors/function_graph.py +1 -2
  88. angr/analyses/forward_analysis/visitors/graph.py +16 -15
  89. angr/analyses/propagator/engine_ail.py +30 -26
  90. angr/analyses/propagator/outdated_definition_walker.py +8 -7
  91. angr/analyses/propagator/propagator.py +11 -13
  92. angr/analyses/proximity_graph.py +21 -21
  93. angr/analyses/reaching_definitions/__init__.py +3 -3
  94. angr/analyses/reaching_definitions/call_trace.py +3 -6
  95. angr/analyses/reaching_definitions/dep_graph.py +41 -48
  96. angr/analyses/reaching_definitions/engine_ail.py +11 -5
  97. angr/analyses/reaching_definitions/engine_vex.py +9 -8
  98. angr/analyses/reaching_definitions/function_handler.py +51 -34
  99. angr/analyses/reaching_definitions/heap_allocator.py +3 -4
  100. angr/analyses/reaching_definitions/rd_initializer.py +8 -8
  101. angr/analyses/reaching_definitions/rd_state.py +57 -58
  102. angr/analyses/reaching_definitions/reaching_definitions.py +18 -17
  103. angr/analyses/reaching_definitions/subject.py +2 -3
  104. angr/analyses/stack_pointer_tracker.py +15 -6
  105. angr/analyses/typehoon/dfa.py +4 -4
  106. angr/analyses/typehoon/simple_solver.py +48 -52
  107. angr/analyses/typehoon/translator.py +3 -6
  108. angr/analyses/typehoon/typeconsts.py +13 -14
  109. angr/analyses/typehoon/typehoon.py +9 -9
  110. angr/analyses/typehoon/typevars.py +18 -17
  111. angr/analyses/variable_recovery/engine_ail.py +5 -5
  112. angr/analyses/variable_recovery/engine_base.py +25 -21
  113. angr/analyses/variable_recovery/irsb_scanner.py +8 -9
  114. angr/analyses/variable_recovery/variable_recovery.py +1 -2
  115. angr/analyses/variable_recovery/variable_recovery_base.py +14 -13
  116. angr/analyses/variable_recovery/variable_recovery_fast.py +8 -8
  117. angr/analyses/veritesting.py +1 -2
  118. angr/analyses/vfg.py +57 -56
  119. angr/analyses/xrefs.py +1 -2
  120. angr/angrdb/db.py +7 -7
  121. angr/angrdb/serializers/kb.py +16 -13
  122. angr/angrdb/serializers/loader.py +1 -2
  123. angr/angrdb/serializers/structured_code.py +2 -2
  124. angr/annocfg.py +1 -2
  125. angr/block.py +16 -6
  126. angr/calling_conventions.py +27 -27
  127. angr/code_location.py +8 -8
  128. angr/codenode.py +1 -2
  129. angr/concretization_strategies/max.py +1 -3
  130. angr/distributed/server.py +1 -3
  131. angr/distributed/worker.py +1 -2
  132. angr/engines/engine.py +2 -3
  133. angr/engines/light/engine.py +4 -4
  134. angr/engines/pcode/behavior.py +20 -2
  135. angr/engines/pcode/emulate.py +1 -1
  136. angr/engines/pcode/engine.py +7 -7
  137. angr/engines/pcode/lifter.py +78 -77
  138. angr/engines/vex/claripy/ccall.py +1 -2
  139. angr/engines/vex/claripy/datalayer.py +1 -2
  140. angr/engines/vex/light/light.py +1 -2
  141. angr/exploration_techniques/tracer.py +4 -4
  142. angr/factory.py +12 -15
  143. angr/flirt/__init__.py +8 -8
  144. angr/flirt/build_sig.py +2 -3
  145. angr/keyed_region.py +2 -2
  146. angr/knowledge_base/knowledge_base.py +3 -3
  147. angr/knowledge_plugins/callsite_prototypes.py +4 -6
  148. angr/knowledge_plugins/cfg/cfg_manager.py +19 -6
  149. angr/knowledge_plugins/cfg/cfg_model.py +26 -27
  150. angr/knowledge_plugins/cfg/cfg_node.py +2 -2
  151. angr/knowledge_plugins/cfg/indirect_jump.py +6 -8
  152. angr/knowledge_plugins/cfg/memory_data.py +8 -9
  153. angr/knowledge_plugins/custom_strings.py +1 -3
  154. angr/knowledge_plugins/debug_variables.py +2 -2
  155. angr/knowledge_plugins/functions/function.py +21 -22
  156. angr/knowledge_plugins/functions/function_manager.py +5 -5
  157. angr/knowledge_plugins/indirect_jumps.py +1 -3
  158. angr/knowledge_plugins/key_definitions/atoms.py +7 -7
  159. angr/knowledge_plugins/key_definitions/definition.py +14 -14
  160. angr/knowledge_plugins/key_definitions/environment.py +5 -7
  161. angr/knowledge_plugins/key_definitions/heap_address.py +1 -3
  162. angr/knowledge_plugins/key_definitions/key_definition_manager.py +3 -2
  163. angr/knowledge_plugins/key_definitions/live_definitions.py +60 -59
  164. angr/knowledge_plugins/key_definitions/liveness.py +16 -16
  165. angr/knowledge_plugins/key_definitions/rd_model.py +15 -15
  166. angr/knowledge_plugins/key_definitions/uses.py +11 -11
  167. angr/knowledge_plugins/patches.py +4 -8
  168. angr/knowledge_plugins/propagations/prop_value.py +10 -9
  169. angr/knowledge_plugins/propagations/propagation_manager.py +3 -5
  170. angr/knowledge_plugins/propagations/propagation_model.py +9 -9
  171. angr/knowledge_plugins/propagations/states.py +52 -22
  172. angr/knowledge_plugins/structured_code/manager.py +2 -2
  173. angr/knowledge_plugins/sync/sync_controller.py +3 -3
  174. angr/knowledge_plugins/variables/variable_access.py +4 -4
  175. angr/knowledge_plugins/variables/variable_manager.py +39 -39
  176. angr/knowledge_plugins/xrefs/xref.py +9 -11
  177. angr/knowledge_plugins/xrefs/xref_manager.py +3 -4
  178. angr/misc/ansi.py +1 -2
  179. angr/misc/autoimport.py +3 -3
  180. angr/misc/plugins.py +9 -9
  181. angr/procedures/definitions/__init__.py +16 -16
  182. angr/procedures/definitions/linux_kernel.py +1 -1
  183. angr/procedures/definitions/parse_win32json.py +1 -1
  184. angr/procedures/java_jni/__init__.py +1 -1
  185. angr/procedures/java_jni/array_operations.py +1 -2
  186. angr/procedures/java_jni/method_calls.py +1 -2
  187. angr/procedures/posix/inet_ntoa.py +1 -2
  188. angr/procedures/stubs/format_parser.py +3 -3
  189. angr/project.py +13 -11
  190. angr/sim_manager.py +12 -12
  191. angr/sim_procedure.py +7 -3
  192. angr/sim_state.py +2 -2
  193. angr/sim_type.py +60 -45
  194. angr/sim_variable.py +5 -5
  195. angr/simos/simos.py +1 -2
  196. angr/simos/userland.py +1 -2
  197. angr/state_plugins/callstack.py +3 -2
  198. angr/state_plugins/history.py +1 -2
  199. angr/state_plugins/solver.py +34 -34
  200. angr/storage/memory_mixins/__init__.py +4 -3
  201. angr/storage/memory_mixins/actions_mixin.py +1 -3
  202. angr/storage/memory_mixins/address_concretization_mixin.py +1 -3
  203. angr/storage/memory_mixins/convenient_mappings_mixin.py +3 -4
  204. angr/storage/memory_mixins/default_filler_mixin.py +1 -1
  205. angr/storage/memory_mixins/label_merger_mixin.py +2 -2
  206. angr/storage/memory_mixins/multi_value_merger_mixin.py +4 -3
  207. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +9 -8
  208. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +12 -11
  209. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +8 -8
  210. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +2 -3
  211. angr/storage/memory_mixins/paged_memory/pages/list_page.py +10 -11
  212. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +11 -10
  213. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +18 -17
  214. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +12 -11
  215. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +3 -3
  216. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +3 -2
  217. angr/storage/memory_mixins/regioned_memory/region_data.py +1 -2
  218. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +2 -2
  219. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +3 -3
  220. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +18 -21
  221. angr/storage/memory_mixins/size_resolution_mixin.py +1 -2
  222. angr/storage/memory_mixins/symbolic_merger_mixin.py +3 -2
  223. angr/storage/memory_mixins/top_merger_mixin.py +3 -2
  224. angr/storage/memory_object.py +2 -4
  225. angr/utils/algo.py +3 -2
  226. angr/utils/dynamic_dictlist.py +5 -5
  227. angr/utils/formatting.py +4 -4
  228. angr/utils/funcid.py +1 -2
  229. angr/utils/graph.py +5 -6
  230. angr/utils/library.py +5 -5
  231. angr/utils/mp.py +5 -4
  232. angr/utils/segment_list.py +3 -4
  233. angr/utils/typing.py +3 -2
  234. {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/METADATA +9 -11
  235. {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/RECORD +239 -236
  236. {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/LICENSE +0 -0
  237. {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/WHEEL +0 -0
  238. {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/entry_points.txt +0 -0
  239. {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,6 @@
3
3
  All type constants used in type inference. They can be mapped, translated, or rewritten to C-style types.
4
4
  """
5
5
 
6
- from typing import List, Optional, Set
7
6
  import functools
8
7
 
9
8
 
@@ -30,7 +29,7 @@ class TypeConstant:
30
29
  def pp_str(self, mapping) -> str: # pylint:disable=unused-argument
31
30
  return repr(self)
32
31
 
33
- def _hash(self, visited: Set[int]): # pylint:disable=unused-argument
32
+ def _hash(self, visited: set[int]): # pylint:disable=unused-argument
34
33
  return hash(type(self))
35
34
 
36
35
  def __eq__(self, other):
@@ -123,13 +122,13 @@ class Double(FloatBase):
123
122
 
124
123
 
125
124
  class Pointer(TypeConstant):
126
- def __init__(self, basetype: Optional[TypeConstant]):
127
- self.basetype: Optional[TypeConstant] = basetype
125
+ def __init__(self, basetype: TypeConstant | None):
126
+ self.basetype: TypeConstant | None = basetype
128
127
 
129
128
  def __eq__(self, other):
130
129
  return type(self) is type(other) and self.basetype == other.basetype
131
130
 
132
- def _hash(self, visited: Set[int]):
131
+ def _hash(self, visited: set[int]):
133
132
  if self.basetype is None:
134
133
  return hash(type(self))
135
134
  return hash((type(self), self.basetype._hash(visited)))
@@ -171,8 +170,8 @@ class Pointer64(Pointer, Int64):
171
170
 
172
171
  class Array(TypeConstant):
173
172
  def __init__(self, element=None, count=None):
174
- self.element: Optional[TypeConstant] = element
175
- self.count: Optional[int] = count
173
+ self.element: TypeConstant | None = element
174
+ self.count: int | None = count
176
175
 
177
176
  @memoize
178
177
  def __repr__(self, memo=None):
@@ -184,7 +183,7 @@ class Array(TypeConstant):
184
183
  def __eq__(self, other):
185
184
  return type(other) is type(self) and self.element == other.element and self.count == other.count
186
185
 
187
- def _hash(self, visited: Set[int]):
186
+ def _hash(self, visited: set[int]):
188
187
  if id(self) in visited:
189
188
  return 0
190
189
  visited.add(id(self))
@@ -200,13 +199,13 @@ class Struct(TypeConstant):
200
199
  self.name = name
201
200
  self.field_names = field_names
202
201
 
203
- def _hash(self, visited: Set[int]):
202
+ def _hash(self, visited: set[int]):
204
203
  if id(self) in visited:
205
204
  return 0
206
205
  visited.add(id(self))
207
206
  return hash((type(self), self._hash_fields(visited)))
208
207
 
209
- def _hash_fields(self, visited: Set[int]):
208
+ def _hash_fields(self, visited: set[int]):
210
209
  keys = sorted(self.fields.keys())
211
210
  tpl = tuple((k, self.fields[k]._hash(visited) if self.fields[k] is not None else None) for k in keys)
212
211
  return hash(tpl)
@@ -226,7 +225,7 @@ class Struct(TypeConstant):
226
225
 
227
226
 
228
227
  class Function(TypeConstant):
229
- def __init__(self, params: List, outputs: List):
228
+ def __init__(self, params: list, outputs: list):
230
229
  self.params = params
231
230
  self.outputs = outputs
232
231
 
@@ -241,7 +240,7 @@ class Function(TypeConstant):
241
240
  return False
242
241
  return self.params == other.params and self.outputs == other.outputs
243
242
 
244
- def _hash(self, visited: Set[int]):
243
+ def _hash(self, visited: set[int]):
245
244
  if id(self) in visited:
246
245
  return 0
247
246
  visited.add(id(self))
@@ -273,7 +272,7 @@ class TypeVariableReference(TypeConstant):
273
272
  #
274
273
 
275
274
 
276
- def int_type(bits: int) -> Optional[Int]:
275
+ def int_type(bits: int) -> Int | None:
277
276
  mapping = {
278
277
  1: Int1,
279
278
  8: Int8,
@@ -287,7 +286,7 @@ def int_type(bits: int) -> Optional[Int]:
287
286
  return None
288
287
 
289
288
 
290
- def float_type(bits: int) -> Optional[FloatBase]:
289
+ def float_type(bits: int) -> FloatBase | None:
291
290
  if bits == 32:
292
291
  return Float()
293
292
  elif bits == 64:
@@ -1,5 +1,5 @@
1
1
  # pylint:disable=bad-builtin
2
- from typing import List, Set, Optional, Dict, Union, TYPE_CHECKING
2
+ from typing import TYPE_CHECKING
3
3
 
4
4
  from ...sim_type import SimStruct, SimTypePointer, SimTypeArray
5
5
  from ..analysis import Analysis, AnalysesHub
@@ -33,8 +33,8 @@ class Typehoon(Analysis):
33
33
  constraints,
34
34
  func_var,
35
35
  ground_truth=None,
36
- var_mapping: Optional[Dict["SimVariable", Set["TypeVariable"]]] = None,
37
- must_struct: Optional[Set["TypeVariable"]] = None,
36
+ var_mapping: dict["SimVariable", set["TypeVariable"]] | None = None,
37
+ must_struct: set["TypeVariable"] | None = None,
38
38
  ):
39
39
  """
40
40
 
@@ -46,8 +46,8 @@ class Typehoon(Analysis):
46
46
  """
47
47
 
48
48
  self.func_var: "TypeVariable" = func_var
49
- self._constraints: Dict["TypeVariable", Set["TypeConstraint"]] = constraints
50
- self._ground_truth: Optional[Dict["TypeVariable", "SimType"]] = ground_truth
49
+ self._constraints: dict["TypeVariable", set["TypeConstraint"]] = constraints
50
+ self._ground_truth: dict["TypeVariable", "SimType"] | None = ground_truth
51
51
  self._var_mapping = var_mapping
52
52
  self._must_struct = must_struct
53
53
 
@@ -66,7 +66,7 @@ class Typehoon(Analysis):
66
66
  # Public methods
67
67
  #
68
68
 
69
- def update_variable_types(self, func_addr: Union[int, str], var_to_typevars):
69
+ def update_variable_types(self, func_addr: int | str, var_to_typevars):
70
70
  for var, typevars in var_to_typevars.items():
71
71
  for typevar in typevars:
72
72
  type_ = self.simtypes_solution.get(typevar, None)
@@ -179,7 +179,7 @@ class Typehoon(Analysis):
179
179
  if specialized is not None:
180
180
  self.solution[tv] = specialized
181
181
 
182
- def _specialize_struct(self, tc, memo: Optional[Set] = None):
182
+ def _specialize_struct(self, tc, memo: set | None = None):
183
183
  if isinstance(tc, Pointer):
184
184
  if memo is not None and tc in memo:
185
185
  return None
@@ -188,8 +188,8 @@ class Typehoon(Analysis):
188
188
  return None
189
189
  return tc.new(specialized)
190
190
 
191
- if isinstance(tc, Struct) and tc.fields:
192
- offsets: List[int] = sorted(list(tc.fields.keys())) # get a sorted list of offsets
191
+ if isinstance(tc, Struct) and tc.fields and min(tc.fields) >= 0:
192
+ offsets: list[int] = sorted(list(tc.fields.keys())) # get a sorted list of offsets
193
193
  offset0 = offsets[0]
194
194
  field0: TypeConstant = tc.fields[offset0]
195
195
 
@@ -1,5 +1,6 @@
1
1
  # pylint:disable=missing-class-docstring
2
- from typing import Dict, Any, Optional, Set, Iterable, Tuple, Union, TYPE_CHECKING
2
+ from typing import Any, Optional, Union, TYPE_CHECKING
3
+ from collections.abc import Iterable
3
4
  from itertools import count
4
5
 
5
6
  from angr.utils.constants import MAX_POINTSTO_BITS
@@ -18,7 +19,7 @@ TypeType = Union["TypeConstant", "TypeVariable", "DerivedTypeVariable"]
18
19
  class TypeConstraint:
19
20
  __slots__ = ()
20
21
 
21
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
22
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
22
23
  raise NotImplementedError()
23
24
 
24
25
 
@@ -32,7 +33,7 @@ class Equivalence(TypeConstraint):
32
33
  self.type_a = type_a
33
34
  self.type_b = type_b
34
35
 
35
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
36
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
36
37
  return f"{self.type_a.pp_str(mapping)} == {self.type_b.pp_str(mapping)}"
37
38
 
38
39
  def __repr__(self):
@@ -56,7 +57,7 @@ class Existence(TypeConstraint):
56
57
  def __init__(self, type_):
57
58
  self.type_ = type_
58
59
 
59
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
60
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
60
61
  return f"V {self.type_.pp_str(mapping)}"
61
62
 
62
63
  def __repr__(self):
@@ -89,7 +90,7 @@ class Subtype(TypeConstraint):
89
90
  self.super_type = super_type
90
91
  self.sub_type = sub_type
91
92
 
92
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
93
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
93
94
  return f"{self.sub_type.pp_str(mapping)} <: {self.super_type.pp_str(mapping)}"
94
95
 
95
96
  def __repr__(self):
@@ -146,7 +147,7 @@ class Add(TypeConstraint):
146
147
  self.type_1 = type_1
147
148
  self.type_r = type_r
148
149
 
149
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
150
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
150
151
  return "{} == {} + {}".format(
151
152
  self.type_r.pp_str(mapping),
152
153
  self.type_0.pp_str(mapping),
@@ -218,7 +219,7 @@ class Sub(TypeConstraint):
218
219
  self.type_1 = type_1
219
220
  self.type_r = type_r
220
221
 
221
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
222
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
222
223
  return "{} == {} - {}".format(
223
224
  self.type_r.pp_str(mapping),
224
225
  self.type_0.pp_str(mapping),
@@ -280,14 +281,14 @@ _typevariable_counter = count()
280
281
  class TypeVariable:
281
282
  __slots__ = ("idx", "name")
282
283
 
283
- def __init__(self, idx: Optional[int] = None, name: Optional[str] = None):
284
+ def __init__(self, idx: int | None = None, name: str | None = None):
284
285
  if idx is None:
285
286
  self.idx: int = next(_typevariable_counter)
286
287
  else:
287
288
  self.idx: int = idx
288
289
  self.name = name
289
290
 
290
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
291
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
291
292
  varname = mapping.get(self, self.name)
292
293
  if varname is None:
293
294
  return repr(self)
@@ -321,9 +322,9 @@ class DerivedTypeVariable(TypeVariable):
321
322
 
322
323
  def __init__(
323
324
  self,
324
- type_var: Optional[Union[TypeVariable, "DerivedTypeVariable"]],
325
+ type_var: Union[TypeVariable, "DerivedTypeVariable"] | None,
325
326
  label,
326
- labels: Optional[Iterable["BaseLabel"]] = None,
327
+ labels: Iterable["BaseLabel"] | None = None,
327
328
  idx=None,
328
329
  ):
329
330
  super().__init__(idx=idx)
@@ -341,7 +342,7 @@ class DerivedTypeVariable(TypeVariable):
341
342
  if label is not None:
342
343
  self.labels = existing_labels + (label,)
343
344
  else:
344
- self.labels: Tuple["BaseLabel"] = existing_labels + tuple(labels)
345
+ self.labels: tuple["BaseLabel"] = existing_labels + tuple(labels)
345
346
 
346
347
  if not self.labels:
347
348
  raise ValueError("A DerivedTypeVariable must have at least one label")
@@ -349,17 +350,17 @@ class DerivedTypeVariable(TypeVariable):
349
350
  def one_label(self) -> Optional["BaseLabel"]:
350
351
  return self.labels[0] if len(self.labels) == 1 else None
351
352
 
352
- def path(self) -> Tuple["BaseLabel"]:
353
+ def path(self) -> tuple["BaseLabel"]:
353
354
  return self.labels
354
355
 
355
- def longest_prefix(self) -> Optional[Union[TypeVariable, "DerivedTypeVariable"]]:
356
+ def longest_prefix(self) -> Union[TypeVariable, "DerivedTypeVariable"] | None:
356
357
  if not self.labels:
357
358
  return None
358
359
  if len(self.labels) == 1:
359
360
  return self.type_var
360
361
  return DerivedTypeVariable(self.type_var, None, labels=self.labels[:-1])
361
362
 
362
- def pp_str(self, mapping: Dict["TypeVariable", Any]) -> str:
363
+ def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
363
364
  return ".".join([self.type_var.pp_str(mapping)] + [repr(lbl) for lbl in self.labels])
364
365
 
365
366
  def __eq__(self, other):
@@ -401,8 +402,8 @@ class TypeVariables:
401
402
  )
402
403
 
403
404
  def __init__(self):
404
- self._typevars: Dict["SimVariable", Set[TypeVariable]] = {}
405
- self._last_typevars: Dict[SimVariable, TypeVariable] = {}
405
+ self._typevars: dict["SimVariable", set[TypeVariable]] = {}
406
+ self._last_typevars: dict[SimVariable, TypeVariable] = {}
406
407
 
407
408
  def copy(self):
408
409
  copied = TypeVariables()
@@ -1,5 +1,5 @@
1
1
  # pylint:disable=arguments-differ,invalid-unary-operand-type
2
- from typing import Optional, TYPE_CHECKING
2
+ from typing import TYPE_CHECKING
3
3
  import logging
4
4
 
5
5
  import ailment
@@ -81,7 +81,7 @@ class SimEngineVRAIL(
81
81
  def _ail_handle_ConditionalJump(self, stmt):
82
82
  self._expr(stmt.condition)
83
83
 
84
- def _ail_handle_Call(self, stmt: ailment.Stmt.Call, is_expr=False) -> Optional[RichR]:
84
+ def _ail_handle_Call(self, stmt: ailment.Stmt.Call, is_expr=False) -> RichR | None:
85
85
  target = stmt.target
86
86
  args = []
87
87
  if stmt.args:
@@ -98,7 +98,7 @@ class SimEngineVRAIL(
98
98
  create_variable = True
99
99
  if not is_expr:
100
100
  # this is a call statement. we need to update the return value register later
101
- ret_expr: Optional[ailment.Expr.Register] = stmt.ret_expr
101
+ ret_expr: ailment.Expr.Register | None = stmt.ret_expr
102
102
  if ret_expr is not None:
103
103
  ret_reg_offset = ret_expr.reg_offset
104
104
  ret_expr_bits = ret_expr.bits
@@ -130,8 +130,8 @@ class SimEngineVRAIL(
130
130
  self.state.add_type_constraint(typevars.Subtype(funcaddr_typevar, load_typevar))
131
131
 
132
132
  # discover the prototype
133
- prototype: Optional[SimTypeFunction] = None
134
- prototype_libname: Optional[str] = None
133
+ prototype: SimTypeFunction | None = None
134
+ prototype_libname: str | None = None
135
135
  if stmt.prototype is not None:
136
136
  prototype = stmt.prototype
137
137
  if isinstance(stmt.target, ailment.Expr.Const):
@@ -1,6 +1,7 @@
1
- from typing import Optional, Set, List, Tuple, Union, TYPE_CHECKING
1
+ from typing import Optional, TYPE_CHECKING
2
2
  import logging
3
3
 
4
+ import ailment
4
5
  import claripy
5
6
 
6
7
  from ...storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
@@ -38,7 +39,7 @@ class RichR:
38
39
  self,
39
40
  data: claripy.ast.Base,
40
41
  variable=None,
41
- typevar: Optional[typevars.TypeVariable] = None,
42
+ typevar: typevars.TypeVariable | None = None,
42
43
  type_constraints=None,
43
44
  ):
44
45
  self.data: claripy.ast.Base = data
@@ -110,7 +111,7 @@ class SimEngineVRBase(SimEngineLight):
110
111
  return False
111
112
 
112
113
  @staticmethod
113
- def _parse_offseted_addr(addr: claripy.ast.BV) -> Optional[Tuple[claripy.ast.BV, claripy.ast.BV, claripy.ast.BV]]:
114
+ def _parse_offseted_addr(addr: claripy.ast.BV) -> tuple[claripy.ast.BV, claripy.ast.BV, claripy.ast.BV] | None:
114
115
  if addr.op == "__add__":
115
116
  if len(addr.args) == 2:
116
117
  concrete_base, byte_offset = None, None
@@ -142,7 +143,7 @@ class SimEngineVRBase(SimEngineLight):
142
143
 
143
144
  def _ensure_variable_existence(
144
145
  self, richr_addr: RichR, codeloc: CodeLocation, src_expr=None
145
- ) -> Optional[List[Tuple[SimVariable, int]]]:
146
+ ) -> list[tuple[SimVariable, int]] | None:
146
147
  data: claripy.ast.Base = richr_addr.data
147
148
 
148
149
  if data is None:
@@ -151,15 +152,15 @@ class SimEngineVRBase(SimEngineLight):
151
152
  if self.state.is_stack_address(data):
152
153
  # this is a stack address
153
154
  # extract stack offset
154
- stack_offset: Optional[int] = self.state.get_stack_offset(data)
155
+ stack_offset: int | None = self.state.get_stack_offset(data)
155
156
 
156
157
  variable_manager = self.variable_manager[self.func_addr]
157
- var_candidates: List[Tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
158
+ var_candidates: list[tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
158
159
  self.block.addr, self.stmt_idx, "memory"
159
160
  )
160
161
 
161
162
  # find the correct variable
162
- existing_vars: List[Tuple[SimVariable, int]] = []
163
+ existing_vars: list[tuple[SimVariable, int]] = []
163
164
  for candidate, offset in var_candidates:
164
165
  if isinstance(candidate, SimStackVariable) and candidate.offset == stack_offset:
165
166
  existing_vars.append((candidate, offset))
@@ -173,7 +174,7 @@ class SimEngineVRBase(SimEngineLight):
173
174
  if variable is None:
174
175
  # TODO: how to determine the size for a lea?
175
176
  try:
176
- vs: Optional[MultiValues] = self.state.stack_region.load(stack_addr, size=1)
177
+ vs: MultiValues | None = self.state.stack_region.load(stack_addr, size=1)
177
178
  except SimMemoryMissingError:
178
179
  vs = None
179
180
 
@@ -248,15 +249,18 @@ class SimEngineVRBase(SimEngineLight):
248
249
  if self.state.is_stack_address(data):
249
250
  # this is a stack address
250
251
  # extract stack offset
251
- stack_offset: Optional[int] = self.state.get_stack_offset(data)
252
+ stack_offset: int | None = self.state.get_stack_offset(data)
252
253
 
253
254
  variable_manager = self.variable_manager[self.func_addr]
254
- var_candidates: List[Tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
255
- self.block.addr, self.stmt_idx, "memory"
255
+ var_candidates: list[tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
256
+ self.block.addr,
257
+ self.stmt_idx,
258
+ "memory",
259
+ block_idx=self.block.idx if isinstance(self.block, ailment.Block) else None,
256
260
  )
257
261
 
258
262
  # find the correct variable
259
- existing_vars: List[Tuple[SimVariable, int]] = []
263
+ existing_vars: list[tuple[SimVariable, int]] = []
260
264
  for candidate, offset in var_candidates:
261
265
  if isinstance(candidate, SimStackVariable) and candidate.offset == stack_offset:
262
266
  existing_vars.append((candidate, offset))
@@ -313,7 +317,7 @@ class SimEngineVRBase(SimEngineLight):
313
317
  # handle register writes
314
318
 
315
319
  # first check if there is an existing variable for the atom at this location already
316
- existing_vars: Set[Tuple[SimVariable, int]] = self.variable_manager[self.func_addr].find_variables_by_atom(
320
+ existing_vars: set[tuple[SimVariable, int]] = self.variable_manager[self.func_addr].find_variables_by_atom(
317
321
  self.block.addr, self.stmt_idx, dst
318
322
  )
319
323
  if not existing_vars:
@@ -473,8 +477,8 @@ class SimEngineVRBase(SimEngineLight):
473
477
  data: RichR,
474
478
  size: int,
475
479
  stmt=None,
476
- offset: Optional[claripy.ast.BV] = None,
477
- elem_size: Optional[claripy.ast.BV] = None,
480
+ offset: claripy.ast.BV | None = None,
481
+ elem_size: claripy.ast.BV | None = None,
478
482
  ):
479
483
  variable_manager = self.variable_manager["global"]
480
484
  if stmt is None:
@@ -636,7 +640,7 @@ class SimEngineVRBase(SimEngineLight):
636
640
  dynamic_offset = None
637
641
 
638
642
  try:
639
- values: Optional[MultiValues] = self.state.stack_region.load(
643
+ values: MultiValues | None = self.state.stack_region.load(
640
644
  self.state.stack_addr_from_offset(concrete_offset),
641
645
  size=size,
642
646
  endness=self.state.arch.memory_endness,
@@ -645,7 +649,7 @@ class SimEngineVRBase(SimEngineLight):
645
649
  except SimMemoryMissingError:
646
650
  values = None
647
651
 
648
- all_vars: Set[Tuple[int, SimVariable]] = set()
652
+ all_vars: set[tuple[int, SimVariable]] = set()
649
653
  if values:
650
654
  for vs in values.values():
651
655
  for v in vs:
@@ -788,8 +792,8 @@ class SimEngineVRBase(SimEngineLight):
788
792
  addr: int,
789
793
  size,
790
794
  expr=None,
791
- offset: Optional[claripy.ast.BV] = None,
792
- elem_size: Optional[claripy.ast.BV] = None,
795
+ offset: claripy.ast.BV | None = None,
796
+ elem_size: claripy.ast.BV | None = None,
793
797
  ) -> RichR:
794
798
  variable_manager = self.variable_manager["global"]
795
799
  if expr is None:
@@ -862,7 +866,7 @@ class SimEngineVRBase(SimEngineLight):
862
866
  codeloc = self._codeloc()
863
867
 
864
868
  try:
865
- values: Optional[MultiValues] = self.state.register_region.load(offset, size=size)
869
+ values: MultiValues | None = self.state.register_region.load(offset, size=size)
866
870
  except SimMemoryMissingError:
867
871
  values = None
868
872
 
@@ -935,7 +939,7 @@ class SimEngineVRBase(SimEngineLight):
935
939
  return RichR(r_value, variable=var, typevar=typevar)
936
940
 
937
941
  def _create_access_typevar(
938
- self, typevar: Union[TypeVariable, DerivedTypeVariable], is_store: bool, size: int, offset: int
942
+ self, typevar: TypeVariable | DerivedTypeVariable, is_store: bool, size: int, offset: int
939
943
  ) -> DerivedTypeVariable:
940
944
  if isinstance(typevar, DerivedTypeVariable):
941
945
  if isinstance(typevar.labels[-1], AddN):
@@ -1,5 +1,4 @@
1
1
  # pylint:disable=no-self-use,unused-argument
2
- from typing import Set, Dict
3
2
 
4
3
  import pyvex
5
4
 
@@ -17,10 +16,10 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
17
16
 
18
17
  # the following variables are for narrowing argument-passing register on 64-bit architectures. they are
19
18
  # initialized before processing each block.
20
- self.tmps_with_64bit_regs: Set[int] = set() # tmps that store 64-bit register values
21
- self.tmps_converted_to_32bit: Set[int] = set() # tmps that store the 64-to-32-bit converted values
22
- self.tmps_assignment_stmtidx: Dict[int, int] = {} # statement IDs for the assignment of each tmp
23
- self.stmts_to_lower: Set[int] = set()
19
+ self.tmps_with_64bit_regs: set[int] = set() # tmps that store 64-bit register values
20
+ self.tmps_converted_to_32bit: set[int] = set() # tmps that store the 64-to-32-bit converted values
21
+ self.tmps_assignment_stmtidx: dict[int, int] = {} # statement IDs for the assignment of each tmp
22
+ self.stmts_to_lower: set[int] = set()
24
23
 
25
24
  # the following variables are for recognizing redundant argument register reads in gcc(?) -O0 binaries.
26
25
  # e.g.,
@@ -28,10 +27,10 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
28
27
  # mov rdi, rax
29
28
  #
30
29
  # we will not create a variable for the register read in the first instruction (read from r9) in this case.
31
- self.tmp_with_reg_as_value: Dict[int, int] = {}
32
- self.reg_with_reg_as_value: Dict[int, int] = {}
33
- self.reg_read_stmt_id: Dict[int, int] = {}
34
- self.reg_read_stmts_to_ignore: Set[int] = set()
30
+ self.tmp_with_reg_as_value: dict[int, int] = {}
31
+ self.reg_with_reg_as_value: dict[int, int] = {}
32
+ self.reg_read_stmt_id: dict[int, int] = {}
33
+ self.reg_read_stmts_to_ignore: set[int] = set()
35
34
 
36
35
  def _top(self, size: int):
37
36
  return None
@@ -1,6 +1,5 @@
1
1
  import logging
2
2
  from collections import defaultdict
3
- from typing import Tuple
4
3
 
5
4
  import claripy
6
5
 
@@ -90,7 +89,7 @@ class VariableRecoveryState(VariableRecoveryStateBase):
90
89
  )
91
90
  concrete_state.inspect.add_breakpoint("mem_write", BP(enabled=True, action=self._hook_memory_write))
92
91
 
93
- def merge(self, others: Tuple["VariableRecoveryState"], successor=None) -> Tuple["VariableRecoveryState", bool]:
92
+ def merge(self, others: tuple["VariableRecoveryState"], successor=None) -> tuple["VariableRecoveryState", bool]:
94
93
  """
95
94
  Merge two abstract states.
96
95
 
@@ -1,5 +1,6 @@
1
1
  import weakref
2
- from typing import List, Generator, Iterable, Tuple, Union, Set, Optional, Dict, Any, TYPE_CHECKING
2
+ from typing import Any, TYPE_CHECKING
3
+ from collections.abc import Generator, Iterable
3
4
  import logging
4
5
  from collections import defaultdict
5
6
 
@@ -51,7 +52,7 @@ def parse_stack_pointer(sp):
51
52
  class VariableAnnotation(Annotation):
52
53
  __slots__ = ("addr_and_variables",)
53
54
 
54
- def __init__(self, addr_and_variables: List[Tuple[int, SimVariable]]):
55
+ def __init__(self, addr_and_variables: list[tuple[int, SimVariable]]):
55
56
  self.addr_and_variables = addr_and_variables
56
57
 
57
58
  @property
@@ -87,7 +88,7 @@ class VariableRecoveryBase(Analysis):
87
88
  self._store_live_variables = store_live_variables
88
89
 
89
90
  self._outstates = {}
90
- self._instates: Dict[Any, VariableRecoveryStateBase] = {}
91
+ self._instates: dict[Any, VariableRecoveryStateBase] = {}
91
92
  self._dominance_frontiers = None
92
93
 
93
94
  #
@@ -211,8 +212,8 @@ class VariableRecoveryStateBase:
211
212
  self.global_region.set_state(self)
212
213
 
213
214
  # Used during merging
214
- self.successor_block_addr: Optional[int] = None
215
- self.phi_variables: Dict[SimVariable, SimVariable] = {}
215
+ self.successor_block_addr: int | None = None
216
+ self.phi_variables: dict[SimVariable, SimVariable] = {}
216
217
 
217
218
  self.typevars = TypeVariables() if typevars is None else typevars
218
219
  self.type_constraints = defaultdict(set) if type_constraints is None else type_constraints
@@ -222,7 +223,7 @@ class VariableRecoveryStateBase:
222
223
  if delayed_type_constraints is None
223
224
  else delayed_type_constraints
224
225
  )
225
- self.stack_offset_typevars: Dict[int, TypeVariable] = (
226
+ self.stack_offset_typevars: dict[int, TypeVariable] = (
226
227
  {} if stack_offset_typevars is None else stack_offset_typevars
227
228
  )
228
229
 
@@ -244,14 +245,14 @@ class VariableRecoveryStateBase:
244
245
  return False
245
246
 
246
247
  @staticmethod
247
- def extract_variables(expr: claripy.ast.Base) -> Generator[Tuple[int, Union[SimVariable, SpOffset]], None, None]:
248
+ def extract_variables(expr: claripy.ast.Base) -> Generator[tuple[int, SimVariable | SpOffset], None, None]:
248
249
  for anno in expr.annotations:
249
250
  if isinstance(anno, VariableAnnotation):
250
251
  yield from anno.addr_and_variables
251
252
 
252
253
  @staticmethod
253
254
  def annotate_with_variables(
254
- expr: claripy.ast.Base, addr_and_variables: Iterable[Tuple[int, Union[SimVariable, SpOffset]]]
255
+ expr: claripy.ast.Base, addr_and_variables: Iterable[tuple[int, SimVariable | SpOffset]]
255
256
  ) -> claripy.ast.Base:
256
257
  expr = expr.replace_annotations((VariableAnnotation(list(addr_and_variables)),))
257
258
  return expr
@@ -276,7 +277,7 @@ class VariableRecoveryStateBase:
276
277
  return False
277
278
 
278
279
  @staticmethod
279
- def extract_stack_offset_from_addr(addr: claripy.ast.Base) -> Optional[claripy.ast.Base]:
280
+ def extract_stack_offset_from_addr(addr: claripy.ast.Base) -> claripy.ast.Base | None:
280
281
  r = None
281
282
  if addr.op == "BVS":
282
283
  if addr.args[0] == "stack_base":
@@ -300,7 +301,7 @@ class VariableRecoveryStateBase:
300
301
  r = r1 - r2
301
302
  return r
302
303
 
303
- def get_stack_offset(self, addr: claripy.ast.Base) -> Optional[int]:
304
+ def get_stack_offset(self, addr: claripy.ast.Base) -> int | None:
304
305
  if "stack_base" in addr.variables:
305
306
  r = VariableRecoveryStateBase.extract_stack_offset_from_addr(addr)
306
307
  if r is None:
@@ -406,17 +407,17 @@ class VariableRecoveryStateBase:
406
407
 
407
408
  @staticmethod
408
409
  def _mo_cmp(
409
- mos_self: Set["SimMemoryObject"], mos_other: Set["SimMemoryObject"], addr: int, size: int
410
+ mos_self: set["SimMemoryObject"], mos_other: set["SimMemoryObject"], addr: int, size: int
410
411
  ): # pylint:disable=unused-argument
411
412
  # comparing bytes from two sets of memory objects
412
413
  # we don't need to resort to byte-level comparison. object-level is good enough.
413
414
 
414
415
  return mos_self == mos_other
415
416
 
416
- def _make_phi_variable(self, values: Set[claripy.ast.Base]) -> Optional[claripy.ast.Base]:
417
+ def _make_phi_variable(self, values: set[claripy.ast.Base]) -> claripy.ast.Base | None:
417
418
  # we only create a new phi variable if the there is at least one variable involved
418
419
  variables = set()
419
- bits: Optional[int] = None
420
+ bits: int | None = None
420
421
  for v in values:
421
422
  bits = v.size()
422
423
  for _, var in self.extract_variables(v):