@@ -436,32 +436,53 @@ module AccessPath {
436
436
* Gets the `ranking`th access-path with `root` and `path` within `bb`.
437
437
* And the access-path has type `type`.
438
438
*/
439
- private DataFlow :: Node rankedAccessPath (
439
+ private ControlFlowNode rankedAccessPath (
440
440
ReachableBasicBlock bb , Root root , string path , int ranking , AccessPathKind type
441
441
) {
442
442
result =
443
- rank [ ranking ] ( DataFlow :: Node ref |
443
+ rank [ ranking ] ( ControlFlowNode ref |
444
444
ref = getAccessTo ( root , path , _) and
445
445
ref .getBasicBlock ( ) = bb
446
446
|
447
- ref order by any ( int i | ref . asExpr ( ) . getEnclosingStmt ( ) = bb .getNode ( i ) )
447
+ ref order by any ( int i | ref = bb .getNode ( i ) )
448
448
) and
449
449
result = getAccessTo ( root , path , type )
450
450
}
451
451
452
452
/**
453
- * Gets an access to `path` from `root` with type `type`.
453
+ * Gets a `ControlFlowNode` for an access to `path` from `root` with type `type`.
454
454
*
455
455
* This predicate uses both the AccessPath API, and the SourceNode API.
456
456
* This ensures that we have basic support for access-paths with ambiguous roots.
457
457
*/
458
458
pragma [ nomagic]
459
- private DataFlow :: Node getAccessTo ( Root root , string path , AccessPathKind type ) {
460
- ( path = fromReference ( result , root ) or result = root . getAPropertyRead ( path ) ) and
461
- type = AccessPathRead ( )
459
+ private ControlFlowNode getAccessTo ( Root root , string path , AccessPathKind type ) {
460
+ type = AccessPathRead ( ) and
461
+ result = getAReadNode ( root , path )
462
462
or
463
- ( path = fromRhs ( result , root ) or result = root .getAPropertyWrite ( path ) .getRhs ( ) ) and
464
- type = AccessPathWrite ( )
463
+ type = AccessPathWrite ( ) and
464
+ result = getAWriteNode ( root , path )
465
+ }
466
+
467
+ /**
468
+ * Gets a `ControlFlowNode` for a read to `path` from `root`.
469
+ */
470
+ private ControlFlowNode getAReadNode ( Root root , string path ) {
471
+ exists ( DataFlow:: PropRead read | read .asExpr ( ) = result |
472
+ path = fromReference ( read , root ) or
473
+ read = root .getAPropertyRead ( path )
474
+ )
475
+ }
476
+
477
+ /**
478
+ * Gets a `ControlFlowNode` for a write to `path` from `root`.
479
+ */
480
+ private ControlFlowNode getAWriteNode ( Root root , string path ) {
481
+ result = root .getAPropertyWrite ( path ) .getWriteNode ( )
482
+ or
483
+ exists ( DataFlow:: PropWrite write | path = fromRhs ( write .getRhs ( ) , root ) |
484
+ result = write .getWriteNode ( )
485
+ )
465
486
}
466
487
467
488
/**
@@ -482,14 +503,14 @@ module AccessPath {
482
503
predicate hasDominatingWrite ( DataFlow:: PropRead read ) {
483
504
// within the same basic block.
484
505
exists ( ReachableBasicBlock bb , Root root , string path , int ranking |
485
- read = rankedAccessPath ( bb , root , path , ranking , AccessPathRead ( ) ) and
506
+ read . asExpr ( ) = rankedAccessPath ( bb , root , path , ranking , AccessPathRead ( ) ) and
486
507
exists ( rankedAccessPath ( bb , root , path , any ( int prev | prev < ranking ) , AccessPathWrite ( ) ) )
487
508
)
488
509
or
489
510
// across basic blocks.
490
511
exists ( Root root , string path |
491
- read = getAccessTo ( root , path , AccessPathRead ( ) ) and
492
- getAWriteBlock ( root , path ) .strictlyDominates ( read .asExpr ( ) . getEnclosingStmt ( ) . getBasicBlock ( ) )
512
+ read . asExpr ( ) = getAccessTo ( root , path , AccessPathRead ( ) ) and
513
+ getAWriteBlock ( root , path ) .strictlyDominates ( read .getBasicBlock ( ) )
493
514
)
494
515
}
495
516
}
0 commit comments