Use a ControlFlowNode based API to determine domination

This commit is contained in:
Erik Krogh Kristensen
2020-06-04 14:55:13 +02:00
parent 926f2c139f
commit 47d52870f2

View File

@@ -436,32 +436,53 @@ module AccessPath {
* Gets the `ranking`th access-path with `root` and `path` within `bb`.
* And the access-path has type `type`.
*/
private DataFlow::Node rankedAccessPath(
private ControlFlowNode rankedAccessPath(
ReachableBasicBlock bb, Root root, string path, int ranking, AccessPathKind type
) {
result =
rank[ranking](DataFlow::Node ref |
rank[ranking](ControlFlowNode ref |
ref = getAccessTo(root, path, _) and
ref.getBasicBlock() = bb
|
ref order by any(int i | ref.asExpr().getEnclosingStmt() = bb.getNode(i))
ref order by any(int i | ref = bb.getNode(i))
) and
result = getAccessTo(root, path, type)
}
/**
* Gets an access to `path` from `root` with type `type`.
* Gets a `ControlFlowNode` for an access to `path` from `root` with type `type`.
*
* This predicate uses both the AccessPath API, and the SourceNode API.
* This ensures that we have basic support for access-paths with ambiguous roots.
*/
pragma[nomagic]
private DataFlow::Node getAccessTo(Root root, string path, AccessPathKind type) {
(path = fromReference(result, root) or result = root.getAPropertyRead(path)) and
type = AccessPathRead()
private ControlFlowNode getAccessTo(Root root, string path, AccessPathKind type) {
type = AccessPathRead() and
result = getAReadNode(root, path)
or
(path = fromRhs(result, root) or result = root.getAPropertyWrite(path).getRhs()) and
type = AccessPathWrite()
type = AccessPathWrite() and
result = getAWriteNode(root, path)
}
/**
* Gets a `ControlFlowNode` for a read to `path` from `root`.
*/
private ControlFlowNode getAReadNode(Root root, string path) {
exists(DataFlow::PropRead read | read.asExpr() = result |
path = fromReference(read, root) or
read = root.getAPropertyRead(path)
)
}
/**
* Gets a `ControlFlowNode` for a write to `path` from `root`.
*/
private ControlFlowNode getAWriteNode(Root root, string path) {
result = root.getAPropertyWrite(path).getWriteNode()
or
exists(DataFlow::PropWrite write | path = fromRhs(write.getRhs(), root) |
result = write.getWriteNode()
)
}
/**
@@ -482,14 +503,14 @@ module AccessPath {
predicate hasDominatingWrite(DataFlow::PropRead read) {
// within the same basic block.
exists(ReachableBasicBlock bb, Root root, string path, int ranking |
read = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and
read.asExpr() = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and
exists(rankedAccessPath(bb, root, path, any(int prev | prev < ranking), AccessPathWrite()))
)
or
// across basic blocks.
exists(Root root, string path |
read = getAccessTo(root, path, AccessPathRead()) and
getAWriteBlock(root, path).strictlyDominates(read.asExpr().getEnclosingStmt().getBasicBlock())
read.asExpr() = getAccessTo(root, path, AccessPathRead()) and
getAWriteBlock(root, path).strictlyDominates(read.getBasicBlock())
)
}
}