@@ -273,6 +273,41 @@ predicate builtin_name_points_to(string name, Object value, ClassObject cls) {
273
273
value = Object:: builtin ( name ) and cls .asBuiltin ( ) = value .asBuiltin ( ) .getClass ( )
274
274
}
275
275
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
+
276
311
module BaseFlow {
277
312
predicate reaches_exit ( EssaVariable var ) { var .getAUse ( ) = var .getScope ( ) .getANormalExit ( ) }
278
313
@@ -283,27 +318,15 @@ module BaseFlow {
283
318
) {
284
319
Stages:: DataFlow:: ref ( ) and
285
320
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 )
291
323
|
292
324
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
- )
306
325
)
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 )
307
330
}
308
331
}
309
332
0 commit comments