Skip to content

Commit 90888e5

Browse files
authored
Merge pull request github#13965 from MathiasVP/better-certain-writes-and-invalid-ptr-deref-prep
C++: Remove more dataflow FPs after frontend upgrade
2 parents bb317bc + 569f3c9 commit 90888e5

File tree

4 files changed

+25
-4
lines changed

4 files changed

+25
-4
lines changed

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,25 @@ private module Cached {
15201520
)
15211521
}
15221522

1523+
/**
1524+
* Holds if `operand.getDef() = instr`, but there exists a `StoreInstruction` that
1525+
* writes to an address that is equivalent to the value computed by `instr` in
1526+
* between `instr` and `operand`, and therefore there should not be flow from `*instr`
1527+
* to `*operand`.
1528+
*/
1529+
pragma[nomagic]
1530+
private predicate isStoredToBetween(Instruction instr, Operand operand) {
1531+
simpleOperandLocalFlowStep(pragma[only_bind_into](instr), pragma[only_bind_into](operand)) and
1532+
exists(StoreInstruction store, IRBlock block, int storeIndex, int instrIndex, int operandIndex |
1533+
store.getDestinationAddress() = instr and
1534+
block.getInstruction(storeIndex) = store and
1535+
block.getInstruction(instrIndex) = instr and
1536+
block.getInstruction(operandIndex) = operand.getUse() and
1537+
instrIndex < storeIndex and
1538+
storeIndex < operandIndex
1539+
)
1540+
}
1541+
15231542
private predicate indirectionInstructionFlow(
15241543
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
15251544
) {
@@ -1529,7 +1548,8 @@ private module Cached {
15291548
simpleOperandLocalFlowStep(pragma[only_bind_into](instr), pragma[only_bind_into](operand))
15301549
|
15311550
hasOperandAndIndex(nodeTo, operand, pragma[only_bind_into](indirectionIndex)) and
1532-
hasInstructionAndIndex(nodeFrom, instr, pragma[only_bind_into](indirectionIndex))
1551+
hasInstructionAndIndex(nodeFrom, instr, pragma[only_bind_into](indirectionIndex)) and
1552+
not isStoredToBetween(instr, operand)
15331553
)
15341554
}
15351555

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import DataFlowImplCommon as DataFlowImplCommon
66
private import DataFlowUtil
77
private import semmle.code.cpp.models.interfaces.PointerWrapper
88
private import DataFlowPrivate
9+
private import semmle.code.cpp.ir.ValueNumbering
910

1011
/**
1112
* Holds if `operand` is an operand that is not used by the dataflow library.
@@ -864,7 +865,7 @@ private module Cached {
864865
* to a specific address.
865866
*/
866867
private predicate isCertainAddress(Operand operand) {
867-
operand.getDef() instanceof VariableAddressInstruction
868+
valueNumberOfOperand(operand).getAnInstruction() instanceof VariableAddressInstruction
868869
or
869870
operand.getType() instanceof Cpp::ReferenceType
870871
}

cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ void test_does_not_write_source_to_dereference()
732732
{
733733
int x;
734734
does_not_write_source_to_dereference(&x);
735-
sink(x); // $ ast,ir=733:7 SPURIOUS: ast,ir=726:11
735+
sink(x); // $ ast=733:7 ir SPURIOUS: ast=726:11
736736
}
737737

738738
void sometimes_calls_sink_eq(int x, int n) {

cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void pointer_test() {
134134
sink(*p3); // $ ast,ir
135135

136136
*p3 = 0;
137-
sink(*p3); // $ SPURIOUS: ast,ir
137+
sink(*p3); // $ SPURIOUS: ast
138138
}
139139

140140
// --- return values ---

0 commit comments

Comments
 (0)