mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Use a ControlFlowNode based API to determine domination
This commit is contained in:
@@ -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())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user