@@ -157,15 +157,20 @@ private predicate hasEntryDef(TrackedVar v, BasicBlock b) {
157157}
158158
159159/** Holds if `n` might update the locally tracked variable `v`. */
160+ overlay [ global]
160161pragma [ nomagic]
161- private predicate uncertainVariableUpdate ( TrackedVar v , ControlFlowNode n , BasicBlock b , int i ) {
162+ private predicate uncertainVariableUpdateImpl ( TrackedVar v , ControlFlowNode n , BasicBlock b , int i ) {
162163 exists ( Call c | c = n .asCall ( ) | updatesNamedField ( c , v , _) ) and
163164 b .getNode ( i ) = n and
164165 hasDominanceInformation ( b )
165166 or
166- uncertainVariableUpdate ( v .getQualifier ( ) , n , b , i )
167+ uncertainVariableUpdateImpl ( v .getQualifier ( ) , n , b , i )
167168}
168169
170+ /** Holds if `n` might update the locally tracked variable `v`. */
171+ predicate uncertainVariableUpdate ( TrackedVar v , ControlFlowNode n , BasicBlock b , int i ) =
172+ forceLocal( uncertainVariableUpdateImpl / 4 ) ( v , n , b , i )
173+
169174private module SsaInput implements SsaImplCommon:: InputSig< Location > {
170175 private import java as J
171176
@@ -345,6 +350,7 @@ private module Cached {
345350 * Constructor --(intraInstanceCallEdge)-->+ Method(setter of this.f)
346351 * ```
347352 */
353+ overlay [ global]
348354 private predicate intraInstanceCallEdge ( Callable c1 , Method m2 ) {
349355 exists ( MethodCall ma , RefType t1 |
350356 ma .getCaller ( ) = c1 and
@@ -365,6 +371,7 @@ private module Cached {
365371 )
366372 }
367373
374+ overlay [ global]
368375 private Callable tgt ( Call c ) {
369376 result = viableImpl_v2 ( c )
370377 or
@@ -374,11 +381,13 @@ private module Cached {
374381 }
375382
376383 /** Holds if `(c1,c2)` is an edge in the call graph. */
384+ overlay [ global]
377385 private predicate callEdge ( Callable c1 , Callable c2 ) {
378386 exists ( Call c | c .getCaller ( ) = c1 and c2 = tgt ( c ) )
379387 }
380388
381389 /** Holds if `(c1,c2)` is an edge in the call graph excluding `intraInstanceCallEdge`. */
390+ overlay [ global]
382391 private predicate crossInstanceCallEdge ( Callable c1 , Callable c2 ) {
383392 callEdge ( c1 , c2 ) and not intraInstanceCallEdge ( c1 , c2 )
384393 }
@@ -392,6 +401,7 @@ private module Cached {
392401 relevantFieldUpdate ( _, f .getField ( ) , _)
393402 }
394403
404+ overlay [ global]
395405 private predicate source ( Call call , TrackedField f , Field field , Callable c , boolean fresh ) {
396406 relevantCall ( call , f ) and
397407 field = f .getField ( ) and
@@ -405,9 +415,11 @@ private module Cached {
405415 * `fresh` indicates whether the instance `this` in `c` has been freshly
406416 * allocated along the call-chain.
407417 */
418+ overlay [ global]
408419 private newtype TCallableNode =
409420 MkCallableNode ( Callable c , boolean fresh ) { source ( _, _, _, c , fresh ) or edge ( _, c , fresh ) }
410421
422+ overlay [ global]
411423 private predicate edge ( TCallableNode n , Callable c2 , boolean f2 ) {
412424 exists ( Callable c1 , boolean f1 | n = MkCallableNode ( c1 , f1 ) |
413425 intraInstanceCallEdge ( c1 , c2 ) and f2 = f1
@@ -417,13 +429,15 @@ private module Cached {
417429 )
418430 }
419431
432+ overlay [ global]
420433 private predicate edge ( TCallableNode n1 , TCallableNode n2 ) {
421434 exists ( Callable c2 , boolean f2 |
422435 edge ( n1 , c2 , f2 ) and
423436 n2 = MkCallableNode ( c2 , f2 )
424437 )
425438 }
426439
440+ overlay [ global]
427441 pragma [ noinline]
428442 private predicate source ( Call call , TrackedField f , Field field , TCallableNode n ) {
429443 exists ( Callable c , boolean fresh |
@@ -432,31 +446,36 @@ private module Cached {
432446 )
433447 }
434448
449+ overlay [ global]
435450 private predicate sink ( Callable c , Field f , TCallableNode n ) {
436451 setsOwnField ( c , f ) and n = MkCallableNode ( c , false )
437452 or
438453 setsOtherField ( c , f ) and n = MkCallableNode ( c , _)
439454 }
440455
456+ overlay [ global]
441457 private predicate prunedNode ( TCallableNode n ) {
442458 sink ( _, _, n )
443459 or
444460 exists ( TCallableNode mid | edge ( n , mid ) and prunedNode ( mid ) )
445461 }
446462
463+ overlay [ global]
447464 private predicate prunedEdge ( TCallableNode n1 , TCallableNode n2 ) {
448465 prunedNode ( n1 ) and
449466 prunedNode ( n2 ) and
450467 edge ( n1 , n2 )
451468 }
452469
470+ overlay [ global]
453471 private predicate edgePlus ( TCallableNode c1 , TCallableNode c2 ) = fastTC( prunedEdge / 2 ) ( c1 , c2 )
454472
455473 /**
456474 * Holds if there exists a call-chain originating in `call` that can update `f` on some instance
457475 * where `f` and `call` share the same enclosing callable in which a
458476 * `FieldRead` of `f` is reachable from `call`.
459477 */
478+ overlay [ global]
460479 pragma [ noopt]
461480 private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) {
462481 exists ( TCallableNode src , TCallableNode sink , Field field |
@@ -467,17 +486,20 @@ private module Cached {
467486 }
468487
469488 bindingset [ call, f]
489+ overlay [ global]
470490 pragma [ inline_late]
471491 private predicate updatesNamedField0 ( Call call , TrackedField f , Callable setter ) {
472492 updatesNamedField ( call , f , setter )
473493 }
474494
495+ overlay [ global]
475496 cached
476497 predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
477498 f = def .getSourceVariable ( ) and
478499 updatesNamedField0 ( def .getCfgNode ( ) .asCall ( ) , f , setter )
479500 }
480501
502+
481503 cached
482504 predicate ssaUncertainImplicitUpdate ( SsaImplicitUpdate def ) {
483505 exists ( SsaSourceVariable v , BasicBlock bb , int i |
@@ -545,6 +567,7 @@ private module Cached {
545567 }
546568
547569 cached
570+ overlay [ global]
548571 module DataFlowIntegration {
549572 import DataFlowIntegrationImpl
550573
0 commit comments