Skip to content

Commit fd8034c

Browse files
committed
C++: Add store step out of read side effects when we don't have a model for the callee. This brings back the lost result on boost.
1 parent a8b4fb6 commit fd8034c

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ private import cpp
22
private import DataFlowUtil
33
private import semmle.code.cpp.ir.IR
44
private import DataFlowDispatch
5+
private import semmle.code.cpp.models.interfaces.DataFlow
56

67
/**
78
* A data flow node that occurs as the argument of a call and is passed as-is
@@ -271,16 +272,31 @@ private predicate callableWithoutDefinitionStoreStep(
271272
) {
272273
exists(
273274
WriteSideEffectInstruction write, ChiInstruction chi, PostUpdateFieldNode post,
274-
Function callable
275+
Function callable, CallInstruction call
275276
|
276277
chi.getPartial() = write and
277278
not chi.isResultConflated() and
278279
post = node2.getPartialDefinition() and
279-
node1.asInstruction() = write and
280280
post.getPreUpdateNode() = getFieldNodeForFieldInstruction(write.getDestinationAddress()) and
281281
f.getADirectField() = post.getPreUpdateNode().getField() and
282-
callable = write.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() and
282+
call = write.getPrimaryInstruction() and
283+
callable = call.getStaticCallTarget() and
283284
not callable.hasDefinition()
285+
|
286+
exists(OutParameterDeref out | out.getIndex() = write.getIndex() |
287+
callable.(DataFlowFunction).hasDataFlow(_, out) and
288+
node1.asInstruction() = write
289+
)
290+
or
291+
// Ideally we shouldn't need to do a store step from a read side effect, but if we don't have a
292+
// model for the callee there might not be flow to the write side effect (since the callee has no
293+
// definition). This case ensures that we propagate dataflow when a field is passed into a
294+
// function that has a write side effect, even though the write side effect doesn't have incoming
295+
// flow.
296+
not callable instanceof DataFlowFunction and
297+
exists(ReadSideEffectInstruction read | call = read.getPrimaryInstruction() |
298+
node1.asInstruction() = read.getSideEffectOperand().getAnyDef()
299+
)
284300
)
285301
}
286302

0 commit comments

Comments
 (0)