@@ -273,6 +273,41 @@ predicate builtin_name_points_to(string name, Object value, ClassObject cls) {
273273 value = Object:: builtin ( name ) and cls .asBuiltin ( ) = value .asBuiltin ( ) .getClass ( )
274274}
275275
276+ pragma [ nomagic]
277+ private predicate essa_var_scope ( SsaSourceVariable var , Scope pred_scope , EssaVariable pred_var ) {
278+ BaseFlow:: reaches_exit ( pred_var ) and
279+ pred_var .getScope ( ) = pred_scope and
280+ var = pred_var .getSourceVariable ( )
281+ }
282+
283+ pragma [ nomagic]
284+ private predicate scope_entry_def_scope (
285+ SsaSourceVariable var , Scope succ_scope , ScopeEntryDefinition succ_def
286+ ) {
287+ var = succ_def .getSourceVariable ( ) and
288+ succ_def .getScope ( ) = succ_scope
289+ }
290+
291+ pragma [ nomagic]
292+ private predicate step_through_init ( Scope succ_scope , Scope pred_scope , Scope init ) {
293+ init .getName ( ) = "__init__" and
294+ init .precedes ( succ_scope ) and
295+ pred_scope .precedes ( init )
296+ }
297+
298+ pragma [ nomagic]
299+ private predicate scope_entry_value_transfer_through_init (
300+ EssaVariable pred_var , Scope pred_scope , ScopeEntryDefinition succ_def , Scope succ_scope
301+ ) {
302+ exists ( SsaSourceVariable var , Scope init |
303+ var instanceof GlobalVariable and
304+ essa_var_scope ( var , pragma [ only_bind_into ] ( pred_scope ) , pred_var ) and
305+ scope_entry_def_scope ( var , succ_scope , succ_def ) and
306+ step_through_init ( succ_scope , pragma [ only_bind_into ] ( pred_scope ) , init ) and
307+ not var .( Variable ) .getAStore ( ) .getScope ( ) = init
308+ )
309+ }
310+
276311module BaseFlow {
277312 predicate reaches_exit ( EssaVariable var ) { var .getAUse ( ) = var .getScope ( ) .getANormalExit ( ) }
278313
@@ -283,27 +318,15 @@ module BaseFlow {
283318 ) {
284319 Stages:: DataFlow:: ref ( ) and
285320 exists ( SsaSourceVariable var |
286- reaches_exit ( pred_var ) and
287- pred_var .getScope ( ) = pred_scope and
288- var = pred_var .getSourceVariable ( ) and
289- var = succ_def .getSourceVariable ( ) and
290- succ_def .getScope ( ) = succ_scope
321+ essa_var_scope ( var , pred_scope , pred_var ) and
322+ scope_entry_def_scope ( var , succ_scope , succ_def )
291323 |
292324 pred_scope .precedes ( succ_scope )
293- or
294- /*
295- * If an `__init__` method does not modify the global variable, then
296- * we can skip it and take the value directly from the module.
297- */
298-
299- exists ( Scope init |
300- init .getName ( ) = "__init__" and
301- init .precedes ( succ_scope ) and
302- pred_scope .precedes ( init ) and
303- not var .( Variable ) .getAStore ( ) .getScope ( ) = init and
304- var instanceof GlobalVariable
305- )
306325 )
326+ or
327+ // If an `__init__` method does not modify the global variable, then
328+ // we can skip it and take the value directly from the module.
329+ scope_entry_value_transfer_through_init ( pred_var , pred_scope , succ_def , succ_scope )
307330 }
308331}
309332
0 commit comments