@@ -157,15 +157,20 @@ private predicate hasEntryDef(TrackedVar v, BasicBlock b) {
157
157
}
158
158
159
159
/** Holds if `n` might update the locally tracked variable `v`. */
160
+ overlay [ global]
160
161
pragma [ 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 ) {
162
163
exists ( Call c | c = n .asCall ( ) | updatesNamedField ( c , v , _) ) and
163
164
b .getNode ( i ) = n and
164
165
hasDominanceInformation ( b )
165
166
or
166
- uncertainVariableUpdate ( v .getQualifier ( ) , n , b , i )
167
+ uncertainVariableUpdateImpl ( v .getQualifier ( ) , n , b , i )
167
168
}
168
169
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
+
169
174
private module SsaInput implements SsaImplCommon:: InputSig< Location > {
170
175
private import java as J
171
176
@@ -345,6 +350,7 @@ private module Cached {
345
350
* Constructor --(intraInstanceCallEdge)-->+ Method(setter of this.f)
346
351
* ```
347
352
*/
353
+ overlay [ global]
348
354
private predicate intraInstanceCallEdge ( Callable c1 , Method m2 ) {
349
355
exists ( MethodCall ma , RefType t1 |
350
356
ma .getCaller ( ) = c1 and
@@ -365,6 +371,7 @@ private module Cached {
365
371
)
366
372
}
367
373
374
+ overlay [ global]
368
375
private Callable tgt ( Call c ) {
369
376
result = viableImpl_v2 ( c )
370
377
or
@@ -374,11 +381,13 @@ private module Cached {
374
381
}
375
382
376
383
/** Holds if `(c1,c2)` is an edge in the call graph. */
384
+ overlay [ global]
377
385
private predicate callEdge ( Callable c1 , Callable c2 ) {
378
386
exists ( Call c | c .getCaller ( ) = c1 and c2 = tgt ( c ) )
379
387
}
380
388
381
389
/** Holds if `(c1,c2)` is an edge in the call graph excluding `intraInstanceCallEdge`. */
390
+ overlay [ global]
382
391
private predicate crossInstanceCallEdge ( Callable c1 , Callable c2 ) {
383
392
callEdge ( c1 , c2 ) and not intraInstanceCallEdge ( c1 , c2 )
384
393
}
@@ -392,6 +401,7 @@ private module Cached {
392
401
relevantFieldUpdate ( _, f .getField ( ) , _)
393
402
}
394
403
404
+ overlay [ global]
395
405
private predicate source ( Call call , TrackedField f , Field field , Callable c , boolean fresh ) {
396
406
relevantCall ( call , f ) and
397
407
field = f .getField ( ) and
@@ -405,9 +415,11 @@ private module Cached {
405
415
* `fresh` indicates whether the instance `this` in `c` has been freshly
406
416
* allocated along the call-chain.
407
417
*/
418
+ overlay [ global]
408
419
private newtype TCallableNode =
409
420
MkCallableNode ( Callable c , boolean fresh ) { source ( _, _, _, c , fresh ) or edge ( _, c , fresh ) }
410
421
422
+ overlay [ global]
411
423
private predicate edge ( TCallableNode n , Callable c2 , boolean f2 ) {
412
424
exists ( Callable c1 , boolean f1 | n = MkCallableNode ( c1 , f1 ) |
413
425
intraInstanceCallEdge ( c1 , c2 ) and f2 = f1
@@ -417,13 +429,15 @@ private module Cached {
417
429
)
418
430
}
419
431
432
+ overlay [ global]
420
433
private predicate edge ( TCallableNode n1 , TCallableNode n2 ) {
421
434
exists ( Callable c2 , boolean f2 |
422
435
edge ( n1 , c2 , f2 ) and
423
436
n2 = MkCallableNode ( c2 , f2 )
424
437
)
425
438
}
426
439
440
+ overlay [ global]
427
441
pragma [ noinline]
428
442
private predicate source ( Call call , TrackedField f , Field field , TCallableNode n ) {
429
443
exists ( Callable c , boolean fresh |
@@ -432,31 +446,36 @@ private module Cached {
432
446
)
433
447
}
434
448
449
+ overlay [ global]
435
450
private predicate sink ( Callable c , Field f , TCallableNode n ) {
436
451
setsOwnField ( c , f ) and n = MkCallableNode ( c , false )
437
452
or
438
453
setsOtherField ( c , f ) and n = MkCallableNode ( c , _)
439
454
}
440
455
456
+ overlay [ global]
441
457
private predicate prunedNode ( TCallableNode n ) {
442
458
sink ( _, _, n )
443
459
or
444
460
exists ( TCallableNode mid | edge ( n , mid ) and prunedNode ( mid ) )
445
461
}
446
462
463
+ overlay [ global]
447
464
private predicate prunedEdge ( TCallableNode n1 , TCallableNode n2 ) {
448
465
prunedNode ( n1 ) and
449
466
prunedNode ( n2 ) and
450
467
edge ( n1 , n2 )
451
468
}
452
469
470
+ overlay [ global]
453
471
private predicate edgePlus ( TCallableNode c1 , TCallableNode c2 ) = fastTC( prunedEdge / 2 ) ( c1 , c2 )
454
472
455
473
/**
456
474
* Holds if there exists a call-chain originating in `call` that can update `f` on some instance
457
475
* where `f` and `call` share the same enclosing callable in which a
458
476
* `FieldRead` of `f` is reachable from `call`.
459
477
*/
478
+ overlay [ global]
460
479
pragma [ noopt]
461
480
private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) {
462
481
exists ( TCallableNode src , TCallableNode sink , Field field |
@@ -467,17 +486,20 @@ private module Cached {
467
486
}
468
487
469
488
bindingset [ call, f]
489
+ overlay [ global]
470
490
pragma [ inline_late]
471
491
private predicate updatesNamedField0 ( Call call , TrackedField f , Callable setter ) {
472
492
updatesNamedField ( call , f , setter )
473
493
}
474
494
495
+ overlay [ global]
475
496
cached
476
497
predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
477
498
f = def .getSourceVariable ( ) and
478
499
updatesNamedField0 ( def .getCfgNode ( ) .asCall ( ) , f , setter )
479
500
}
480
501
502
+
481
503
cached
482
504
predicate ssaUncertainImplicitUpdate ( SsaImplicitUpdate def ) {
483
505
exists ( SsaSourceVariable v , BasicBlock bb , int i |
@@ -545,6 +567,7 @@ private module Cached {
545
567
}
546
568
547
569
cached
570
+ overlay [ global]
548
571
module DataFlowIntegration {
549
572
import DataFlowIntegrationImpl
550
573
0 commit comments