Skip to content

Commit 3388ca4

Browse files
committed
Python: sync dataflow library
1 parent e259281 commit 3388ca4

1 file changed

Lines changed: 61 additions & 2 deletions

File tree

python/ql/src/experimental/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,67 @@ private module Cached {
330330
import Final
331331
}
332332

333+
import FlowThrough
334+
335+
cached
336+
private module DispatchWithCallContext {
337+
/**
338+
* Holds if the call context `ctx` reduces the set of viable run-time
339+
* dispatch targets of call `call` in `c`.
340+
*/
341+
cached
342+
predicate reducedViableImplInCallContext(DataFlowCall call, DataFlowCallable c, DataFlowCall ctx) {
343+
exists(int tgts, int ctxtgts |
344+
mayBenefitFromCallContext(call, c) and
345+
c = viableCallable(ctx) and
346+
ctxtgts = count(viableImplInCallContext(call, ctx)) and
347+
tgts = strictcount(viableCallable(call)) and
348+
ctxtgts < tgts
349+
)
350+
}
351+
352+
/**
353+
* Gets a viable run-time dispatch target for the call `call` in the
354+
* context `ctx`. This is restricted to those calls for which a context
355+
* makes a difference.
356+
*/
357+
cached
358+
DataFlowCallable prunedViableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
359+
result = viableImplInCallContext(call, ctx) and
360+
reducedViableImplInCallContext(call, _, ctx)
361+
}
362+
363+
/**
364+
* Holds if flow returning from callable `c` to call `call` might return
365+
* further and if this path restricts the set of call sites that can be
366+
* returned to.
367+
*/
368+
cached
369+
predicate reducedViableImplInReturn(DataFlowCallable c, DataFlowCall call) {
370+
exists(int tgts, int ctxtgts |
371+
mayBenefitFromCallContext(call, _) and
372+
c = viableCallable(call) and
373+
ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContext(call, ctx)) and
374+
tgts = strictcount(DataFlowCall ctx | viableCallable(ctx) = call.getEnclosingCallable()) and
375+
ctxtgts < tgts
376+
)
377+
}
378+
379+
/**
380+
* Gets a viable run-time dispatch target for the call `call` in the
381+
* context `ctx`. This is restricted to those calls and results for which
382+
* the return flow from the result to `call` restricts the possible context
383+
* `ctx`.
384+
*/
385+
cached
386+
DataFlowCallable prunedViableImplInCallContextReverse(DataFlowCall call, DataFlowCall ctx) {
387+
result = viableImplInCallContext(call, ctx) and
388+
reducedViableImplInReturn(result, call)
389+
}
390+
}
391+
392+
import DispatchWithCallContext
393+
333394
/**
334395
* Holds if `p` can flow to the pre-update node associated with post-update
335396
* node `n`, in the same callable, using only value-preserving steps.
@@ -371,8 +432,6 @@ private module Cached {
371432
store(node1, tc.getContent(), node2, contentType, tc.getContainerType())
372433
}
373434

374-
import FlowThrough
375-
376435
/**
377436
* Holds if the call context `call` either improves virtual dispatch in
378437
* `callable` or if it allows us to prune unreachable nodes in `callable`.

0 commit comments

Comments
 (0)