Data flow: Adjust parameterMatch join-orders

This commit is contained in:
Tom Hvitved
2021-12-07 20:29:00 +01:00
parent 31374b485c
commit 07ca1c2ec0
2 changed files with 39 additions and 28 deletions

View File

@@ -62,6 +62,18 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
tupleLimit = 1000
}
/**
* Holds if `arg` is an argument of `call` with an argument position that matches
* parameter position `ppos`.
*/
pragma[noinline]
predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) {
exists(ArgumentPosition apos |
arg.argumentOf(call, apos) and
parameterMatch(ppos, apos)
)
}
/**
* Provides a simple data-flow analysis for resolving lambda calls. The analysis
* currently excludes read-steps, store-steps, and flow-through.
@@ -71,31 +83,27 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
* calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly.
*/
private module LambdaFlow {
private predicate viableParamNonLambda(DataFlowCall call, ArgumentPosition apos, ParamNode p) {
exists(ParameterPosition ppos |
p.isParameterOf(viableCallable(call), ppos) and
parameterMatch(ppos, apos)
)
pragma[noinline]
private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallable(call), ppos)
}
private predicate viableParamLambda(DataFlowCall call, ArgumentPosition apos, ParamNode p) {
exists(ParameterPosition ppos |
p.isParameterOf(viableCallableLambda(call, _), ppos) and
parameterMatch(ppos, apos)
)
pragma[noinline]
private predicate viableParamLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), ppos)
}
private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(ArgumentPosition pos |
viableParamNonLambda(call, pos, p) and
arg.argumentOf(call, pos)
exists(ParameterPosition ppos |
viableParamNonLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}
private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(ArgumentPosition pos |
viableParamLambda(call, pos, p) and
arg.argumentOf(call, pos)
exists(ParameterPosition ppos |
viableParamLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}

View File

@@ -710,6 +710,14 @@ module Private {
)
}
pragma[noinline]
private predicate viableParam(
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
) {
p.isParameterOf(sc, ppos) and
sc = viableCallable(call)
}
/**
* Holds if values stored inside content `c` are cleared inside a
* callable to which `arg` is an argument.
@@ -718,23 +726,18 @@ module Private {
* `arg` (see comment for `summaryClearsContent`).
*/
predicate summaryClearsContentArg(ArgNode arg, Content c) {
exists(DataFlowCall call, ParameterPosition ppos, ArgumentPosition apos |
viableCallable(call).(SummarizedCallable).clearsContent(ppos, c) and
arg.argumentOf(call, apos) and
parameterMatch(ppos, apos)
exists(DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos |
argumentPositionMatch(call, arg, ppos) and
viableParam(call, sc, ppos, _) and
sc.clearsContent(ppos, c)
)
}
pragma[nomagic]
private ParamNode summaryArgParam(ArgNode arg, ReturnKindExt rk, OutNodeExt out) {
exists(
DataFlowCall call, ParameterPosition ppos, ArgumentPosition apos,
SummarizedCallable callable
|
arg.argumentOf(call, apos) and
viableCallable(call) = callable and
result.isParameterOf(callable, ppos) and
parameterMatch(ppos, apos) and
exists(DataFlowCall call, ParameterPosition ppos, SummarizedCallable sc |
argumentPositionMatch(call, arg, ppos) and
viableParam(call, sc, ppos, result) and
out = rk.getAnOutNode(call)
)
}