@@ -293,6 +293,74 @@ def get_all_dependencies_ssa(
293
293
return context .context [KEY_SSA ]
294
294
295
295
296
+ def get_must_depends_on (variable : SUPPORTED_TYPES ) -> List :
297
+ """
298
+ Return must dependency of a variable if exist otherwise return None.
299
+
300
+ :param variable: target variable whose must dependency needs to be computed
301
+ :return: Variable | None
302
+ """
303
+ must_dependencies = compute_must_dependencies (variable )
304
+ if len (must_dependencies ) > 1 or len (must_dependencies ) == 0 :
305
+ return []
306
+ return [list (must_dependencies )[0 ]]
307
+
308
+
309
+ def compute_must_dependencies (v : SUPPORTED_TYPES ) -> Set [Variable ]:
310
+ if isinstance (v , (SolidityVariableComposed , Constant )) or (
311
+ v .function .visibility in ["public" , "external" ] and v in v .function .parameters
312
+ ):
313
+ return set ([v ])
314
+
315
+ function_dependencies = {}
316
+ function_dependencies ["context" ] = {}
317
+ lvalues = []
318
+
319
+ for node in v .function .nodes :
320
+ for ir in node .irs_ssa :
321
+ if isinstance (ir , OperationWithLValue ) and ir .lvalue :
322
+ if isinstance (ir .lvalue , LocalIRVariable ) and ir .lvalue .is_storage :
323
+ continue
324
+ if isinstance (ir .lvalue , ReferenceVariable ):
325
+ lvalue = ir .lvalue .points_to
326
+ if lvalue :
327
+ lvalues .append ((lvalue , v .function , ir ))
328
+ lvalues .append ((ir .lvalue , v .function , ir ))
329
+
330
+ for lvalue_details in lvalues :
331
+ lvalue = lvalue_details [0 ]
332
+ ir = lvalue_details [2 ]
333
+
334
+ if not lvalue in function_dependencies ["context" ]:
335
+ function_dependencies ["context" ][lvalue ] = set ()
336
+ read : Union [List [Union [LVALUE , SolidityVariableComposed ]], List [SlithIRVariable ]]
337
+
338
+ if isinstance (ir , Index ):
339
+ read = [ir .variable_left ]
340
+ elif isinstance (ir , InternalCall ) and ir .function :
341
+ read = ir .function .return_values_ssa
342
+ else :
343
+ read = ir .read
344
+ for variable in read :
345
+ # if not isinstance(variable, Constant):
346
+ function_dependencies ["context" ][lvalue ].add (variable )
347
+ function_dependencies ["context" ] = convert_to_non_ssa (function_dependencies ["context" ])
348
+
349
+ must_dependencies = set ()
350
+ data_dependencies = (
351
+ list (function_dependencies ["context" ][v ])
352
+ if function_dependencies ["context" ] is not None
353
+ else []
354
+ )
355
+ for i , data_dependency in enumerate (data_dependencies ):
356
+ result = compute_must_dependencies (data_dependency )
357
+ if i > 0 :
358
+ must_dependencies = must_dependencies .intersection (result )
359
+ else :
360
+ must_dependencies = must_dependencies .union (result )
361
+ return must_dependencies
362
+
363
+
296
364
# endregion
297
365
###################################################################################
298
366
###################################################################################
0 commit comments