@@ -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 , BasicBlock > {
170175 class SourceVariable = SsaSourceVariable ;
171176
@@ -335,6 +340,7 @@ private module Cached {
335340 * Constructor --(intraInstanceCallEdge)-->+ Method(setter of this.f)
336341 * ```
337342 */
343+ overlay [ global]
338344 private predicate intraInstanceCallEdge ( Callable c1 , Method m2 ) {
339345 exists ( MethodCall ma , RefType t1 |
340346 ma .getCaller ( ) = c1 and
@@ -355,6 +361,7 @@ private module Cached {
355361 )
356362 }
357363
364+ overlay [ global]
358365 private Callable tgt ( Call c ) {
359366 result = viableImpl_v2 ( c )
360367 or
@@ -364,11 +371,13 @@ private module Cached {
364371 }
365372
366373 /** Holds if `(c1,c2)` is an edge in the call graph. */
374+ overlay [ global]
367375 private predicate callEdge ( Callable c1 , Callable c2 ) {
368376 exists ( Call c | c .getCaller ( ) = c1 and c2 = tgt ( c ) )
369377 }
370378
371379 /** Holds if `(c1,c2)` is an edge in the call graph excluding `intraInstanceCallEdge`. */
380+ overlay [ global]
372381 private predicate crossInstanceCallEdge ( Callable c1 , Callable c2 ) {
373382 callEdge ( c1 , c2 ) and not intraInstanceCallEdge ( c1 , c2 )
374383 }
@@ -382,6 +391,7 @@ private module Cached {
382391 relevantFieldUpdate ( _, f .getField ( ) , _)
383392 }
384393
394+ overlay [ global]
385395 private predicate source ( Call call , TrackedField f , Field field , Callable c , boolean fresh ) {
386396 relevantCall ( call , f ) and
387397 field = f .getField ( ) and
@@ -395,9 +405,11 @@ private module Cached {
395405 * `fresh` indicates whether the instance `this` in `c` has been freshly
396406 * allocated along the call-chain.
397407 */
408+ overlay [ global]
398409 private newtype TCallableNode =
399410 MkCallableNode ( Callable c , boolean fresh ) { source ( _, _, _, c , fresh ) or edge ( _, c , fresh ) }
400411
412+ overlay [ global]
401413 private predicate edge ( TCallableNode n , Callable c2 , boolean f2 ) {
402414 exists ( Callable c1 , boolean f1 | n = MkCallableNode ( c1 , f1 ) |
403415 intraInstanceCallEdge ( c1 , c2 ) and f2 = f1
@@ -407,13 +419,15 @@ private module Cached {
407419 )
408420 }
409421
422+ overlay [ global]
410423 private predicate edge ( TCallableNode n1 , TCallableNode n2 ) {
411424 exists ( Callable c2 , boolean f2 |
412425 edge ( n1 , c2 , f2 ) and
413426 n2 = MkCallableNode ( c2 , f2 )
414427 )
415428 }
416429
430+ overlay [ global]
417431 pragma [ noinline]
418432 private predicate source ( Call call , TrackedField f , Field field , TCallableNode n ) {
419433 exists ( Callable c , boolean fresh |
@@ -422,31 +436,36 @@ private module Cached {
422436 )
423437 }
424438
439+ overlay [ global]
425440 private predicate sink ( Callable c , Field f , TCallableNode n ) {
426441 setsOwnField ( c , f ) and n = MkCallableNode ( c , false )
427442 or
428443 setsOtherField ( c , f ) and n = MkCallableNode ( c , _)
429444 }
430445
446+ overlay [ global]
431447 private predicate prunedNode ( TCallableNode n ) {
432448 sink ( _, _, n )
433449 or
434450 exists ( TCallableNode mid | edge ( n , mid ) and prunedNode ( mid ) )
435451 }
436452
453+ overlay [ global]
437454 private predicate prunedEdge ( TCallableNode n1 , TCallableNode n2 ) {
438455 prunedNode ( n1 ) and
439456 prunedNode ( n2 ) and
440457 edge ( n1 , n2 )
441458 }
442459
460+ overlay [ global]
443461 private predicate edgePlus ( TCallableNode c1 , TCallableNode c2 ) = fastTC( prunedEdge / 2 ) ( c1 , c2 )
444462
445463 /**
446464 * Holds if there exists a call-chain originating in `call` that can update `f` on some instance
447465 * where `f` and `call` share the same enclosing callable in which a
448466 * `FieldRead` of `f` is reachable from `call`.
449467 */
468+ overlay [ global]
450469 pragma [ noopt]
451470 private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) {
452471 exists ( TCallableNode src , TCallableNode sink , Field field |
@@ -457,11 +476,13 @@ private module Cached {
457476 }
458477
459478 bindingset [ call, f]
479+ overlay [ global]
460480 pragma [ inline_late]
461481 private predicate updatesNamedField0 ( Call call , TrackedField f , Callable setter ) {
462482 updatesNamedField ( call , f , setter )
463483 }
464484
485+ overlay [ global]
465486 cached
466487 predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
467488 f = def .getSourceVariable ( ) and
@@ -534,6 +555,7 @@ private module Cached {
534555 Impl:: phiHasInputFromBlock ( phi , inp , bb )
535556 }
536557
558+ overlay [ global]
537559 cached
538560 module DataFlowIntegration {
539561 import DataFlowIntegrationImpl
0 commit comments