@@ -345,6 +345,7 @@ private module Cached {
345
345
* Constructor --(intraInstanceCallEdge)-->+ Method(setter of this.f)
346
346
* ```
347
347
*/
348
+ overlay [ global]
348
349
private predicate intraInstanceCallEdge ( Callable c1 , Method m2 ) {
349
350
exists ( MethodCall ma , RefType t1 |
350
351
ma .getCaller ( ) = c1 and
@@ -365,6 +366,7 @@ private module Cached {
365
366
)
366
367
}
367
368
369
+ overlay [ global]
368
370
private Callable tgt ( Call c ) {
369
371
result = viableImpl_v2 ( c )
370
372
or
@@ -374,11 +376,13 @@ private module Cached {
374
376
}
375
377
376
378
/** Holds if `(c1,c2)` is an edge in the call graph. */
379
+ overlay [ global]
377
380
private predicate callEdge ( Callable c1 , Callable c2 ) {
378
381
exists ( Call c | c .getCaller ( ) = c1 and c2 = tgt ( c ) )
379
382
}
380
383
381
384
/** Holds if `(c1,c2)` is an edge in the call graph excluding `intraInstanceCallEdge`. */
385
+ overlay [ global]
382
386
private predicate crossInstanceCallEdge ( Callable c1 , Callable c2 ) {
383
387
callEdge ( c1 , c2 ) and not intraInstanceCallEdge ( c1 , c2 )
384
388
}
@@ -392,6 +396,7 @@ private module Cached {
392
396
relevantFieldUpdate ( _, f .getField ( ) , _)
393
397
}
394
398
399
+ overlay [ global]
395
400
private predicate source ( Call call , TrackedField f , Field field , Callable c , boolean fresh ) {
396
401
relevantCall ( call , f ) and
397
402
field = f .getField ( ) and
@@ -405,9 +410,11 @@ private module Cached {
405
410
* `fresh` indicates whether the instance `this` in `c` has been freshly
406
411
* allocated along the call-chain.
407
412
*/
413
+ overlay [ global]
408
414
private newtype TCallableNode =
409
415
MkCallableNode ( Callable c , boolean fresh ) { source ( _, _, _, c , fresh ) or edge ( _, c , fresh ) }
410
416
417
+ overlay [ global]
411
418
private predicate edge ( TCallableNode n , Callable c2 , boolean f2 ) {
412
419
exists ( Callable c1 , boolean f1 | n = MkCallableNode ( c1 , f1 ) |
413
420
intraInstanceCallEdge ( c1 , c2 ) and f2 = f1
@@ -417,13 +424,15 @@ private module Cached {
417
424
)
418
425
}
419
426
427
+ overlay [ global]
420
428
private predicate edge ( TCallableNode n1 , TCallableNode n2 ) {
421
429
exists ( Callable c2 , boolean f2 |
422
430
edge ( n1 , c2 , f2 ) and
423
431
n2 = MkCallableNode ( c2 , f2 )
424
432
)
425
433
}
426
434
435
+ overlay [ global]
427
436
pragma [ noinline]
428
437
private predicate source ( Call call , TrackedField f , Field field , TCallableNode n ) {
429
438
exists ( Callable c , boolean fresh |
@@ -432,52 +441,64 @@ private module Cached {
432
441
)
433
442
}
434
443
444
+ overlay [ global]
435
445
private predicate sink ( Callable c , Field f , TCallableNode n ) {
436
446
setsOwnField ( c , f ) and n = MkCallableNode ( c , false )
437
447
or
438
448
setsOtherField ( c , f ) and n = MkCallableNode ( c , _)
439
449
}
440
450
451
+ overlay [ global]
441
452
private predicate prunedNode ( TCallableNode n ) {
442
453
sink ( _, _, n )
443
454
or
444
455
exists ( TCallableNode mid | edge ( n , mid ) and prunedNode ( mid ) )
445
456
}
446
457
458
+ overlay [ global]
447
459
private predicate prunedEdge ( TCallableNode n1 , TCallableNode n2 ) {
448
460
prunedNode ( n1 ) and
449
461
prunedNode ( n2 ) and
450
462
edge ( n1 , n2 )
451
463
}
452
464
465
+ overlay [ global]
453
466
private predicate edgePlus ( TCallableNode c1 , TCallableNode c2 ) = fastTC( prunedEdge / 2 ) ( c1 , c2 )
454
467
455
468
/**
456
469
* Holds if there exists a call-chain originating in `call` that can update `f` on some instance
457
470
* where `f` and `call` share the same enclosing callable in which a
458
471
* `FieldRead` of `f` is reachable from `call`.
459
472
*/
473
+ overlay [ global]
460
474
pragma [ noopt]
461
- private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) {
475
+ private predicate updatesNamedFieldImplGlobal ( Call call , TrackedField f , Callable setter ) {
462
476
exists ( TCallableNode src , TCallableNode sink , Field field |
463
477
source ( call , f , field , src ) and
464
478
sink ( setter , field , sink ) and
465
479
( src = sink or edgePlus ( src , sink ) )
466
480
)
467
481
}
468
482
483
+ private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) =
484
+ forceLocal( updatesNamedFieldImplGlobal / 3 ) ( call , f , setter )
485
+
469
486
bindingset [ call, f]
470
487
pragma [ inline_late]
471
488
private predicate updatesNamedField0 ( Call call , TrackedField f , Callable setter ) {
472
489
updatesNamedField ( call , f , setter )
473
490
}
474
491
475
492
cached
476
- predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
493
+ predicate defUpdatesNamedFieldImpl ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
477
494
f = def .getSourceVariable ( ) and
478
495
updatesNamedField0 ( def .getCfgNode ( ) .asCall ( ) , f , setter )
479
496
}
480
497
498
+ cached
499
+ predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) =
500
+ forceLocal( defUpdatesNamedFieldImpl / 3 ) ( def , f , setter )
501
+
481
502
cached
482
503
predicate ssaUncertainImplicitUpdate ( SsaImplicitUpdate def ) {
483
504
exists ( SsaSourceVariable v , BasicBlock bb , int i |
0 commit comments