Skip to content

Commit a6a694d

Browse files
committed
C++: Use DataFlowIntegration in IteratorFlow.
1 parent aaa7e4c commit a6a694d

File tree

2 files changed

+55
-47
lines changed

2 files changed

+55
-47
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,46 @@ module IteratorFlow {
18341834

18351835
private module IteratorSsa = SsaImpl::Make<Location, SsaInput>;
18361836

1837+
private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig {
1838+
private import codeql.util.Void
1839+
1840+
class Expr extends Instruction {
1841+
Expr() {
1842+
exists(IRBlock bb, int i |
1843+
SsaInput::variableRead(bb, i, _, true) and
1844+
this = bb.getInstruction(i)
1845+
)
1846+
}
1847+
1848+
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
1849+
}
1850+
1851+
predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() }
1852+
1853+
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
1854+
1855+
class Guard extends Void {
1856+
predicate controlsBranchEdge(
1857+
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
1858+
) {
1859+
none()
1860+
}
1861+
}
1862+
1863+
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
1864+
none()
1865+
}
1866+
1867+
predicate supportBarrierGuardsOnPhiEdges() { none() }
1868+
}
1869+
1870+
private module DataFlowIntegrationImpl =
1871+
IteratorSsa::DataFlowIntegration<DataFlowIntegrationInput>;
1872+
1873+
private class IteratorSynthNode extends DataFlowIntegrationImpl::SsaNode {
1874+
IteratorSynthNode() { not this.asDefinition() instanceof IteratorSsa::WriteDefinition }
1875+
}
1876+
18371877
private class Def extends IteratorSsa::Definition {
18381878
final override Location getLocation() { result = this.getImpl().getLocation() }
18391879

@@ -1859,37 +1899,15 @@ module IteratorFlow {
18591899
int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() }
18601900
}
18611901

1862-
private class PhiNode extends IteratorSsa::DefinitionExt {
1863-
PhiNode() {
1864-
this instanceof IteratorSsa::PhiNode or
1865-
this instanceof IteratorSsa::PhiReadNode
1866-
}
1867-
1868-
SsaIteratorNode getNode() { result.getIteratorFlowNode() = this }
1869-
}
1870-
1871-
cached
1872-
private module IteratorSsaCached {
1873-
cached
1874-
predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) {
1875-
IteratorSsa::adjacentDefReadExt(_, sv, bb1, i1, bb2, i2)
1876-
or
1877-
exists(PhiNode phi |
1878-
IteratorSsa::lastRefRedefExt(_, sv, bb1, i1, phi) and
1879-
phi.definesAt(sv, bb2, i2, _)
1880-
)
1881-
}
1882-
}
1883-
18841902
/** The set of nodes necessary for iterator flow. */
1885-
class IteratorFlowNode instanceof PhiNode {
1903+
class IteratorFlowNode instanceof IteratorSynthNode {
18861904
/** Gets a textual representation of this node. */
18871905
string toString() { result = super.toString() }
18881906

18891907
/** Gets the type of this node. */
18901908
DataFlowType getType() {
18911909
exists(Ssa::SourceVariable sv |
1892-
super.definesAt(sv, _, _, _) and
1910+
super.getSourceVariable() = sv and
18931911
result = sv.getType()
18941912
)
18951913
}
@@ -1901,43 +1919,33 @@ module IteratorFlow {
19011919
Location getLocation() { result = super.getBasicBlock().getLocation() }
19021920
}
19031921

1904-
private import IteratorSsaCached
1905-
19061922
private predicate defToNode(Node node, Def def) {
19071923
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
19081924
or
19091925
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
19101926
}
19111927

1912-
private predicate nodeToDefOrUse(Node node, SourceVariable sv, IRBlock bb, int i) {
1913-
exists(Def def |
1914-
def.hasIndexInBlock(bb, i, sv) and
1915-
defToNode(node, def)
1916-
)
1928+
bindingset[result, v]
1929+
pragma[inline_late]
1930+
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
1931+
result = n.(SsaIteratorNode).getIteratorFlowNode()
19171932
or
1918-
useToNode(bb, i, sv, node)
1919-
}
1920-
1921-
private predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) {
1922-
exists(PhiNode phi |
1923-
phi.definesAt(sv, bb, i, _) and
1924-
nodeTo = phi.getNode()
1933+
exists(Ssa::UseImpl use, IRBlock bb, int i |
1934+
result.(DataFlowIntegrationImpl::ExprNode).getExpr().hasCfgNode(bb, i) and
1935+
use.hasIndexInBlock(bb, i, v) and
1936+
use.getNode() = n
19251937
)
19261938
or
1927-
exists(Ssa::UseImpl use |
1928-
use.hasIndexInBlock(bb, i, sv) and
1929-
nodeTo = use.getNode()
1930-
)
1939+
defToNode(n, result.(DataFlowIntegrationImpl::SsaDefinitionNode).getDefinition())
19311940
}
19321941

19331942
/**
19341943
* Holds if `nodeFrom` flows to `nodeTo` in a single step.
19351944
*/
19361945
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
1937-
exists(SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2 |
1938-
adjacentDefRead(bb1, i1, sv, bb2, i2) and
1939-
nodeToDefOrUse(nodeFrom, sv, bb1, i1) and
1940-
useToNode(bb2, i2, sv, nodeTo)
1946+
exists(SourceVariable v |
1947+
nodeFrom != nodeTo and
1948+
DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v), _)
19411949
)
19421950
}
19431951
}

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
10691069

10701070
bindingset[result, v]
10711071
pragma[inline_late]
1072-
DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
1072+
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
10731073
result = n.(SsaSynthNode).getSynthNode()
10741074
or
10751075
exists(UseImpl use, IRBlock bb, int i |

0 commit comments

Comments
 (0)