@@ -345,6 +345,7 @@ private module Cached {
345345 * Constructor --(intraInstanceCallEdge)-->+ Method(setter of this.f)
346346 * ```
347347 */
348+ overlay [ global]
348349 private predicate intraInstanceCallEdge ( Callable c1 , Method m2 ) {
349350 exists ( MethodCall ma , RefType t1 |
350351 ma .getCaller ( ) = c1 and
@@ -365,6 +366,7 @@ private module Cached {
365366 )
366367 }
367368
369+ overlay [ global]
368370 private Callable tgt ( Call c ) {
369371 result = viableImpl_v2 ( c )
370372 or
@@ -374,11 +376,13 @@ private module Cached {
374376 }
375377
376378 /** Holds if `(c1,c2)` is an edge in the call graph. */
379+ overlay [ global]
377380 private predicate callEdge ( Callable c1 , Callable c2 ) {
378381 exists ( Call c | c .getCaller ( ) = c1 and c2 = tgt ( c ) )
379382 }
380383
381384 /** Holds if `(c1,c2)` is an edge in the call graph excluding `intraInstanceCallEdge`. */
385+ overlay [ global]
382386 private predicate crossInstanceCallEdge ( Callable c1 , Callable c2 ) {
383387 callEdge ( c1 , c2 ) and not intraInstanceCallEdge ( c1 , c2 )
384388 }
@@ -392,6 +396,7 @@ private module Cached {
392396 relevantFieldUpdate ( _, f .getField ( ) , _)
393397 }
394398
399+ overlay [ global]
395400 private predicate source ( Call call , TrackedField f , Field field , Callable c , boolean fresh ) {
396401 relevantCall ( call , f ) and
397402 field = f .getField ( ) and
@@ -405,9 +410,11 @@ private module Cached {
405410 * `fresh` indicates whether the instance `this` in `c` has been freshly
406411 * allocated along the call-chain.
407412 */
413+ overlay [ global]
408414 private newtype TCallableNode =
409415 MkCallableNode ( Callable c , boolean fresh ) { source ( _, _, _, c , fresh ) or edge ( _, c , fresh ) }
410416
417+ overlay [ global]
411418 private predicate edge ( TCallableNode n , Callable c2 , boolean f2 ) {
412419 exists ( Callable c1 , boolean f1 | n = MkCallableNode ( c1 , f1 ) |
413420 intraInstanceCallEdge ( c1 , c2 ) and f2 = f1
@@ -417,13 +424,15 @@ private module Cached {
417424 )
418425 }
419426
427+ overlay [ global]
420428 private predicate edge ( TCallableNode n1 , TCallableNode n2 ) {
421429 exists ( Callable c2 , boolean f2 |
422430 edge ( n1 , c2 , f2 ) and
423431 n2 = MkCallableNode ( c2 , f2 )
424432 )
425433 }
426434
435+ overlay [ global]
427436 pragma [ noinline]
428437 private predicate source ( Call call , TrackedField f , Field field , TCallableNode n ) {
429438 exists ( Callable c , boolean fresh |
@@ -432,52 +441,64 @@ private module Cached {
432441 )
433442 }
434443
444+ overlay [ global]
435445 private predicate sink ( Callable c , Field f , TCallableNode n ) {
436446 setsOwnField ( c , f ) and n = MkCallableNode ( c , false )
437447 or
438448 setsOtherField ( c , f ) and n = MkCallableNode ( c , _)
439449 }
440450
451+ overlay [ global]
441452 private predicate prunedNode ( TCallableNode n ) {
442453 sink ( _, _, n )
443454 or
444455 exists ( TCallableNode mid | edge ( n , mid ) and prunedNode ( mid ) )
445456 }
446457
458+ overlay [ global]
447459 private predicate prunedEdge ( TCallableNode n1 , TCallableNode n2 ) {
448460 prunedNode ( n1 ) and
449461 prunedNode ( n2 ) and
450462 edge ( n1 , n2 )
451463 }
452464
465+ overlay [ global]
453466 private predicate edgePlus ( TCallableNode c1 , TCallableNode c2 ) = fastTC( prunedEdge / 2 ) ( c1 , c2 )
454467
455468 /**
456469 * Holds if there exists a call-chain originating in `call` that can update `f` on some instance
457470 * where `f` and `call` share the same enclosing callable in which a
458471 * `FieldRead` of `f` is reachable from `call`.
459472 */
473+ overlay [ global]
460474 pragma [ noopt]
461- private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) {
475+ private predicate updatesNamedFieldImplGlobal ( Call call , TrackedField f , Callable setter ) {
462476 exists ( TCallableNode src , TCallableNode sink , Field field |
463477 source ( call , f , field , src ) and
464478 sink ( setter , field , sink ) and
465479 ( src = sink or edgePlus ( src , sink ) )
466480 )
467481 }
468482
483+ private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) =
484+ forceLocal( updatesNamedFieldImplGlobal / 3 ) ( call , f , setter )
485+
469486 bindingset [ call, f]
470487 pragma [ inline_late]
471488 private predicate updatesNamedField0 ( Call call , TrackedField f , Callable setter ) {
472489 updatesNamedField ( call , f , setter )
473490 }
474491
475492 cached
476- predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
493+ predicate defUpdatesNamedFieldImpl ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
477494 f = def .getSourceVariable ( ) and
478495 updatesNamedField0 ( def .getCfgNode ( ) .asCall ( ) , f , setter )
479496 }
480497
498+ cached
499+ predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) =
500+ forceLocal( defUpdatesNamedFieldImpl / 3 ) ( def , f , setter )
501+
481502 cached
482503 predicate ssaUncertainImplicitUpdate ( SsaImplicitUpdate def ) {
483504 exists ( SsaSourceVariable v , BasicBlock bb , int i |
0 commit comments