mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C++: Use DataFlowIntegration in IteratorFlow.
This commit is contained in:
@@ -1834,6 +1834,46 @@ module IteratorFlow {
|
||||
|
||||
private module IteratorSsa = SsaImpl::Make<Location, SsaInput>;
|
||||
|
||||
private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig {
|
||||
private import codeql.util.Void
|
||||
|
||||
class Expr extends Instruction {
|
||||
Expr() {
|
||||
exists(IRBlock bb, int i |
|
||||
SsaInput::variableRead(bb, i, _, true) and
|
||||
this = bb.getInstruction(i)
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
|
||||
}
|
||||
|
||||
predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() }
|
||||
|
||||
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
|
||||
|
||||
class Guard extends Void {
|
||||
predicate controlsBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
none()
|
||||
}
|
||||
|
||||
predicate supportBarrierGuardsOnPhiEdges() { none() }
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl =
|
||||
IteratorSsa::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
|
||||
private class IteratorSynthNode extends DataFlowIntegrationImpl::SsaNode {
|
||||
IteratorSynthNode() { not this.asDefinition() instanceof IteratorSsa::WriteDefinition }
|
||||
}
|
||||
|
||||
private class Def extends IteratorSsa::Definition {
|
||||
final override Location getLocation() { result = this.getImpl().getLocation() }
|
||||
|
||||
@@ -1859,37 +1899,15 @@ module IteratorFlow {
|
||||
int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() }
|
||||
}
|
||||
|
||||
private class PhiNode extends IteratorSsa::DefinitionExt {
|
||||
PhiNode() {
|
||||
this instanceof IteratorSsa::PhiNode or
|
||||
this instanceof IteratorSsa::PhiReadNode
|
||||
}
|
||||
|
||||
SsaIteratorNode getNode() { result.getIteratorFlowNode() = this }
|
||||
}
|
||||
|
||||
cached
|
||||
private module IteratorSsaCached {
|
||||
cached
|
||||
predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) {
|
||||
IteratorSsa::adjacentDefReadExt(_, sv, bb1, i1, bb2, i2)
|
||||
or
|
||||
exists(PhiNode phi |
|
||||
IteratorSsa::lastRefRedefExt(_, sv, bb1, i1, phi) and
|
||||
phi.definesAt(sv, bb2, i2, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The set of nodes necessary for iterator flow. */
|
||||
class IteratorFlowNode instanceof PhiNode {
|
||||
class IteratorFlowNode instanceof IteratorSynthNode {
|
||||
/** Gets a textual representation of this node. */
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
/** Gets the type of this node. */
|
||||
DataFlowType getType() {
|
||||
exists(Ssa::SourceVariable sv |
|
||||
super.definesAt(sv, _, _, _) and
|
||||
super.getSourceVariable() = sv and
|
||||
result = sv.getType()
|
||||
)
|
||||
}
|
||||
@@ -1901,43 +1919,33 @@ module IteratorFlow {
|
||||
Location getLocation() { result = super.getBasicBlock().getLocation() }
|
||||
}
|
||||
|
||||
private import IteratorSsaCached
|
||||
|
||||
private predicate defToNode(Node node, Def def) {
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
}
|
||||
|
||||
private predicate nodeToDefOrUse(Node node, SourceVariable sv, IRBlock bb, int i) {
|
||||
exists(Def def |
|
||||
def.hasIndexInBlock(bb, i, sv) and
|
||||
defToNode(node, def)
|
||||
bindingset[result, v]
|
||||
pragma[inline_late]
|
||||
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
|
||||
result = n.(SsaIteratorNode).getIteratorFlowNode()
|
||||
or
|
||||
exists(Ssa::UseImpl use, IRBlock bb, int i |
|
||||
result.(DataFlowIntegrationImpl::ExprNode).getExpr().hasCfgNode(bb, i) and
|
||||
use.hasIndexInBlock(bb, i, v) and
|
||||
use.getNode() = n
|
||||
)
|
||||
or
|
||||
useToNode(bb, i, sv, node)
|
||||
}
|
||||
|
||||
private predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) {
|
||||
exists(PhiNode phi |
|
||||
phi.definesAt(sv, bb, i, _) and
|
||||
nodeTo = phi.getNode()
|
||||
)
|
||||
or
|
||||
exists(Ssa::UseImpl use |
|
||||
use.hasIndexInBlock(bb, i, sv) and
|
||||
nodeTo = use.getNode()
|
||||
)
|
||||
defToNode(n, result.(DataFlowIntegrationImpl::SsaDefinitionNode).getDefinition())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` flows to `nodeTo` in a single step.
|
||||
*/
|
||||
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
exists(SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2 |
|
||||
adjacentDefRead(bb1, i1, sv, bb2, i2) and
|
||||
nodeToDefOrUse(nodeFrom, sv, bb1, i1) and
|
||||
useToNode(bb2, i2, sv, nodeTo)
|
||||
exists(SourceVariable v |
|
||||
nodeFrom != nodeTo and
|
||||
DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v), _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,7 +1069,7 @@ module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
|
||||
|
||||
bindingset[result, v]
|
||||
pragma[inline_late]
|
||||
DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
|
||||
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
|
||||
result = n.(SsaSynthNode).getSynthNode()
|
||||
or
|
||||
exists(UseImpl use, IRBlock bb, int i |
|
||||
|
||||
Reference in New Issue
Block a user