Skip to content

Commit 794d96e

Browse files
committed
C++: Use call context information to perform function-pointer resolution.
1 parent 2d24387 commit 794d96e

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,36 @@ private predicate functionSignature(Function f, string qualifiedName, int nparam
231231
* Holds if the set of viable implementations that can be called by `call`
232232
* might be improved by knowing the call context.
233233
*/
234-
predicate mayBenefitFromCallContext(CallInstruction call, Function f) { none() }
234+
predicate mayBenefitFromCallContext(CallInstruction call, Function f) {
235+
mayBenefitFromCallContext(call, f, _)
236+
}
237+
238+
/**
239+
* Holds if `call` is a call through a function pointer, and the pointer
240+
* value is given as the `arg`'th argument to `f`.
241+
*
242+
* Note that `f` may be several layers up through the call chain.
243+
*/
244+
private predicate mayBenefitFromCallContext(
245+
VirtualDispatch::DataSensitiveCall call, Function f, int arg
246+
) {
247+
exists(InitializeParameterInstruction init |
248+
not exists(call.getStaticCallTarget()) and
249+
init.getEnclosingFunction() = f and
250+
call.flowsFrom(DataFlow::instructionNode(init), _) and
251+
init.getParameter().getIndex() = arg
252+
)
253+
}
235254

236255
/**
237256
* Gets a viable dispatch target of `call` in the context `ctx`. This is
238257
* restricted to those `call`s for which a context might make a difference.
239258
*/
240-
Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) { none() }
259+
Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) {
260+
result = viableCallable(call) and
261+
exists(int i, Function f |
262+
mayBenefitFromCallContext(pragma[only_bind_into](call), f, i) and
263+
f = ctx.getStaticCallTarget() and
264+
result = ctx.getArgument(i).getUnconvertedResultExpression().(FunctionAccess).getTarget()
265+
)
266+
}

0 commit comments

Comments
 (0)