Skip to content

Commit 20900da

Browse files
committed
C++: Handle reverse flow when 'nodeTo' is an instruction.
1 parent e124a70 commit 20900da

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

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

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,16 +1696,7 @@ private module Cached {
16961696
// Reverse flow: data that flows from the definition node back into the indirection returned
16971697
// by a function. This allows data to flow 'in' through references returned by a modeled
16981698
// function such as `operator[]`.
1699-
exists(Operand address, int indirectionIndex |
1700-
nodeHasOperand(nodeTo.(IndirectReturnOutNode), address, indirectionIndex)
1701-
|
1702-
exists(StoreInstruction store |
1703-
nodeHasInstruction(nodeFrom, store, indirectionIndex - 1) and
1704-
store.getDestinationAddressOperand() = address
1705-
)
1706-
or
1707-
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
1708-
)
1699+
reverseFlow(nodeFrom, nodeTo)
17091700
}
17101701

17111702
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
@@ -1736,6 +1727,39 @@ private module Cached {
17361727
)
17371728
)
17381729
}
1730+
1731+
private predicate reverseFlow(Node nodeFrom, Node nodeTo) {
1732+
reverseFlowOperand(nodeFrom, nodeTo)
1733+
or
1734+
reverseFlowInstruction(nodeFrom, nodeTo)
1735+
}
1736+
1737+
private predicate reverseFlowOperand(Node nodeFrom, IndirectReturnOutNode nodeTo) {
1738+
exists(Operand address, int indirectionIndex |
1739+
nodeHasOperand(nodeTo, address, indirectionIndex)
1740+
|
1741+
exists(StoreInstruction store |
1742+
nodeHasInstruction(nodeFrom, store, indirectionIndex - 1) and
1743+
store.getDestinationAddressOperand() = address
1744+
)
1745+
or
1746+
// We also want a write coming out of an `OutNode` to flow `nodeTo`.
1747+
// This is different from `reverseFlowInstruction` since `nodeFrom` can never
1748+
// be an `OutNode` when it's defined by an instruction.
1749+
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
1750+
)
1751+
}
1752+
1753+
private predicate reverseFlowInstruction(Node nodeFrom, IndirectReturnOutNode nodeTo) {
1754+
exists(Instruction address, int indirectionIndex |
1755+
nodeHasInstruction(nodeTo, address, indirectionIndex)
1756+
|
1757+
exists(StoreInstruction store |
1758+
nodeHasInstruction(nodeFrom, store, indirectionIndex - 1) and
1759+
store.getDestinationAddress() = address
1760+
)
1761+
)
1762+
}
17391763
}
17401764

17411765
import Cached

0 commit comments

Comments
 (0)