@@ -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 , BasicBlock > {
170
175
class SourceVariable = SsaSourceVariable ;
171
176
@@ -335,6 +340,7 @@ private module Cached {
335
340
* Constructor --(intraInstanceCallEdge)-->+ Method(setter of this.f)
336
341
* ```
337
342
*/
343
+ overlay [ global]
338
344
private predicate intraInstanceCallEdge ( Callable c1 , Method m2 ) {
339
345
exists ( MethodCall ma , RefType t1 |
340
346
ma .getCaller ( ) = c1 and
@@ -355,6 +361,7 @@ private module Cached {
355
361
)
356
362
}
357
363
364
+ overlay [ global]
358
365
private Callable tgt ( Call c ) {
359
366
result = viableImpl_v2 ( c )
360
367
or
@@ -364,11 +371,13 @@ private module Cached {
364
371
}
365
372
366
373
/** Holds if `(c1,c2)` is an edge in the call graph. */
374
+ overlay [ global]
367
375
private predicate callEdge ( Callable c1 , Callable c2 ) {
368
376
exists ( Call c | c .getCaller ( ) = c1 and c2 = tgt ( c ) )
369
377
}
370
378
371
379
/** Holds if `(c1,c2)` is an edge in the call graph excluding `intraInstanceCallEdge`. */
380
+ overlay [ global]
372
381
private predicate crossInstanceCallEdge ( Callable c1 , Callable c2 ) {
373
382
callEdge ( c1 , c2 ) and not intraInstanceCallEdge ( c1 , c2 )
374
383
}
@@ -382,6 +391,7 @@ private module Cached {
382
391
relevantFieldUpdate ( _, f .getField ( ) , _)
383
392
}
384
393
394
+ overlay [ global]
385
395
private predicate source ( Call call , TrackedField f , Field field , Callable c , boolean fresh ) {
386
396
relevantCall ( call , f ) and
387
397
field = f .getField ( ) and
@@ -395,9 +405,11 @@ private module Cached {
395
405
* `fresh` indicates whether the instance `this` in `c` has been freshly
396
406
* allocated along the call-chain.
397
407
*/
408
+ overlay [ global]
398
409
private newtype TCallableNode =
399
410
MkCallableNode ( Callable c , boolean fresh ) { source ( _, _, _, c , fresh ) or edge ( _, c , fresh ) }
400
411
412
+ overlay [ global]
401
413
private predicate edge ( TCallableNode n , Callable c2 , boolean f2 ) {
402
414
exists ( Callable c1 , boolean f1 | n = MkCallableNode ( c1 , f1 ) |
403
415
intraInstanceCallEdge ( c1 , c2 ) and f2 = f1
@@ -407,13 +419,15 @@ private module Cached {
407
419
)
408
420
}
409
421
422
+ overlay [ global]
410
423
private predicate edge ( TCallableNode n1 , TCallableNode n2 ) {
411
424
exists ( Callable c2 , boolean f2 |
412
425
edge ( n1 , c2 , f2 ) and
413
426
n2 = MkCallableNode ( c2 , f2 )
414
427
)
415
428
}
416
429
430
+ overlay [ global]
417
431
pragma [ noinline]
418
432
private predicate source ( Call call , TrackedField f , Field field , TCallableNode n ) {
419
433
exists ( Callable c , boolean fresh |
@@ -422,31 +436,36 @@ private module Cached {
422
436
)
423
437
}
424
438
439
+ overlay [ global]
425
440
private predicate sink ( Callable c , Field f , TCallableNode n ) {
426
441
setsOwnField ( c , f ) and n = MkCallableNode ( c , false )
427
442
or
428
443
setsOtherField ( c , f ) and n = MkCallableNode ( c , _)
429
444
}
430
445
446
+ overlay [ global]
431
447
private predicate prunedNode ( TCallableNode n ) {
432
448
sink ( _, _, n )
433
449
or
434
450
exists ( TCallableNode mid | edge ( n , mid ) and prunedNode ( mid ) )
435
451
}
436
452
453
+ overlay [ global]
437
454
private predicate prunedEdge ( TCallableNode n1 , TCallableNode n2 ) {
438
455
prunedNode ( n1 ) and
439
456
prunedNode ( n2 ) and
440
457
edge ( n1 , n2 )
441
458
}
442
459
460
+ overlay [ global]
443
461
private predicate edgePlus ( TCallableNode c1 , TCallableNode c2 ) = fastTC( prunedEdge / 2 ) ( c1 , c2 )
444
462
445
463
/**
446
464
* Holds if there exists a call-chain originating in `call` that can update `f` on some instance
447
465
* where `f` and `call` share the same enclosing callable in which a
448
466
* `FieldRead` of `f` is reachable from `call`.
449
467
*/
468
+ overlay [ global]
450
469
pragma [ noopt]
451
470
private predicate updatesNamedFieldImpl ( Call call , TrackedField f , Callable setter ) {
452
471
exists ( TCallableNode src , TCallableNode sink , Field field |
@@ -457,11 +476,13 @@ private module Cached {
457
476
}
458
477
459
478
bindingset [ call, f]
479
+ overlay [ global]
460
480
pragma [ inline_late]
461
481
private predicate updatesNamedField0 ( Call call , TrackedField f , Callable setter ) {
462
482
updatesNamedField ( call , f , setter )
463
483
}
464
484
485
+ overlay [ global]
465
486
cached
466
487
predicate defUpdatesNamedField ( SsaImplicitUpdate def , TrackedField f , Callable setter ) {
467
488
f = def .getSourceVariable ( ) and
@@ -534,6 +555,7 @@ private module Cached {
534
555
Impl:: phiHasInputFromBlock ( phi , inp , bb )
535
556
}
536
557
558
+ overlay [ global]
537
559
cached
538
560
module DataFlowIntegration {
539
561
import DataFlowIntegrationImpl
0 commit comments