Skip to content

Commit e58b99d

Browse files
committed
C++: Don't carry the sources around as columns during the main loop of product flow.
1 parent a0a8468 commit e58b99d

File tree

1 file changed

+67
-18
lines changed

1 file changed

+67
-18
lines changed

cpp/ql/lib/experimental/semmle/code/cpp/dataflow/ProductFlow.qll

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -324,25 +324,71 @@ module ProductFlow {
324324

325325
module Flow2 = DataFlow::GlobalWithState<Config2>;
326326

327+
private predicate isSourcePair(Flow1::PathNode node1, Flow2::PathNode node2) {
328+
Config::isSourcePair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState())
329+
}
330+
331+
private predicate isSinkPair(Flow1::PathNode node1, Flow2::PathNode node2) {
332+
Config::isSinkPair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState())
333+
}
334+
335+
pragma[assume_small_delta]
327336
pragma[nomagic]
328-
private predicate reachableInterprocEntry(
329-
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode node1, Flow2::PathNode node2
330-
) {
331-
Config::isSourcePair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState()) and
332-
node1 = source1 and
333-
node2 = source2
337+
private predicate fwdReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) {
338+
isSourcePair(node1, node2)
334339
or
335-
exists(
336-
Flow1::PathNode midEntry1, Flow2::PathNode midEntry2, Flow1::PathNode midExit1,
337-
Flow2::PathNode midExit2
340+
exists(Flow1::PathNode pred1, Flow2::PathNode pred2 |
341+
fwdReachableInterprocEntry(pred1, pred2) and
342+
isSuccessor(pred1, pred2, node1, node2)
343+
)
344+
}
345+
346+
bindingset[pred1, pred2]
347+
bindingset[succ1, succ2]
348+
private predicate isSuccessor(
349+
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
350+
) {
351+
exists(Flow1::PathNode mid1, Flow2::PathNode mid2 |
352+
localPathStep1*(pred1, mid1) and
353+
localPathStep2*(pred2, mid2)
338354
|
339-
reachableInterprocEntry(source1, source2, midEntry1, midEntry2) and
340-
interprocEdgePair(midExit1, midExit2, node1, node2) and
341-
localPathStep1*(midEntry1, midExit1) and
342-
localPathStep2*(midEntry2, midExit2)
355+
isSinkPair(mid1, mid2) and
356+
succ1 = mid1 and
357+
succ2 = mid2
358+
or
359+
interprocEdgePair(mid1, mid2, succ1, succ2)
343360
)
344361
}
345362

363+
pragma[assume_small_delta]
364+
pragma[nomagic]
365+
private predicate revReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) {
366+
fwdReachableInterprocEntry(node1, node2) and
367+
(
368+
isSinkPair(node1, node2)
369+
or
370+
exists(Flow1::PathNode succ1, Flow2::PathNode succ2 |
371+
revReachableInterprocEntry(succ1, succ2) and
372+
isSuccessor(node1, node2, succ1, succ2)
373+
)
374+
)
375+
}
376+
377+
private newtype TNodePair =
378+
TMkNodePair(Flow1::PathNode node1, Flow2::PathNode node2) {
379+
revReachableInterprocEntry(node1, node2)
380+
}
381+
382+
private predicate pathSucc(TNodePair n1, TNodePair n2) {
383+
exists(Flow1::PathNode n11, Flow2::PathNode n12, Flow1::PathNode n21, Flow2::PathNode n22 |
384+
n1 = TMkNodePair(n11, n12) and
385+
n2 = TMkNodePair(n21, n22) and
386+
isSuccessor(n11, n12, n21, n22)
387+
)
388+
}
389+
390+
private predicate pathSuccPlus(TNodePair n1, TNodePair n2) = fastTC(pathSucc/2)(n1, n2)
391+
346392
private predicate localPathStep1(Flow1::PathNode pred, Flow1::PathNode succ) {
347393
Flow1::PathGraph::edges(pred, succ) and
348394
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
@@ -474,11 +520,14 @@ module ProductFlow {
474520
private predicate reachable(
475521
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode sink1, Flow2::PathNode sink2
476522
) {
477-
exists(Flow1::PathNode mid1, Flow2::PathNode mid2 |
478-
reachableInterprocEntry(source1, source2, mid1, mid2) and
479-
Config::isSinkPair(sink1.getNode(), sink1.getState(), sink2.getNode(), sink2.getState()) and
480-
localPathStep1*(mid1, sink1) and
481-
localPathStep2*(mid2, sink2)
523+
isSourcePair(source1, source2) and
524+
isSinkPair(sink1, sink2) and
525+
exists(TNodePair n1, TNodePair n2 |
526+
n1 = TMkNodePair(source1, source2) and
527+
n2 = TMkNodePair(sink1, sink2)
528+
|
529+
pathSuccPlus(n1, n2) or
530+
n1 = n2
482531
)
483532
}
484533
}

0 commit comments

Comments
 (0)