Skip to content

Commit 38d0bb4

Browse files
authored
Merge pull request #7260 from hvitved/dataflow/argument-parameter-matching
Data flow: Introduce `ParameterPosition` and `ArgumentPosition`
2 parents ede1503 + 283173a commit 38d0bb4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2167
-1605
lines changed

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowDispatch.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
private import cpp
2+
private import semmle.code.cpp.dataflow.internal.DataFlowPrivate
3+
private import semmle.code.cpp.dataflow.internal.DataFlowUtil
24

35
/**
46
* Gets a function that might be called by `call`.
@@ -63,3 +65,17 @@ predicate mayBenefitFromCallContext(Call call, Function f) { none() }
6365
* restricted to those `call`s for which a context might make a difference.
6466
*/
6567
Function viableImplInCallContext(Call call, Call ctx) { none() }
68+
69+
/** A parameter position represented by an integer. */
70+
class ParameterPosition extends int {
71+
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
72+
}
73+
74+
/** An argument position represented by an integer. */
75+
class ArgumentPosition extends int {
76+
ArgumentPosition() { any(ArgumentNode a).argumentOf(_, this) }
77+
}
78+
79+
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
80+
pragma[inline]
81+
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
256256
private class ParamNodeEx extends NodeEx {
257257
ParamNodeEx() { this.asNode() instanceof ParamNode }
258258

259-
predicate isParameterOf(DataFlowCallable c, int i) {
260-
this.asNode().(ParamNode).isParameterOf(c, i)
259+
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
260+
this.asNode().(ParamNode).isParameterOf(c, pos)
261261
}
262262

263-
int getPosition() { this.isParameterOf(_, result) }
263+
ParameterPosition getPosition() { this.isParameterOf(_, result) }
264264

265265
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
266266
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
14471447
}
14481448

14491449
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
1450-
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
1450+
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
14511451
parameterFlow(p, ap, ap0, c, config) and
14521452
c = ret.getEnclosingCallable() and
14531453
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
21422142
}
21432143

21442144
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
2145-
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
2145+
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
21462146
parameterFlow(p, ap, ap0, c, config) and
21472147
c = ret.getEnclosingCallable() and
21482148
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
29082908
}
29092909

29102910
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
2911-
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
2911+
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
29122912
parameterFlow(p, ap, ap0, c, config) and
29132913
c = ret.getEnclosingCallable() and
29142914
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
29922992

29932993
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
29942994

2995-
int getParameterPos() { p.isParameterOf(_, result) }
2995+
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
29962996

29972997
ParamNodeEx getParamNode() { result = p }
29982998

@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
36393639
*/
36403640
pragma[noinline]
36413641
private predicate pathIntoArg(
3642-
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
3643-
Configuration config
3642+
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
3643+
AccessPathApprox apa, Configuration config
36443644
) {
3645-
exists(ArgNode arg |
3645+
exists(ArgNode arg, ArgumentPosition apos |
36463646
arg = mid.getNodeEx().asNode() and
36473647
cc = mid.getCallContext() and
3648-
arg.argumentOf(call, i) and
3648+
arg.argumentOf(call, apos) and
36493649
ap = mid.getAp() and
36503650
apa = ap.getApprox() and
3651-
config = mid.getConfiguration()
3651+
config = mid.getConfiguration() and
3652+
parameterMatch(ppos, apos)
36523653
)
36533654
}
36543655

36553656
pragma[nomagic]
36563657
private predicate parameterCand(
3657-
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
3658+
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
36583659
) {
36593660
exists(ParamNodeEx p |
36603661
Stage4::revFlow(p, _, _, apa, config) and
3661-
p.isParameterOf(callable, i)
3662+
p.isParameterOf(callable, pos)
36623663
)
36633664
}
36643665

36653666
pragma[nomagic]
36663667
private predicate pathIntoCallable0(
3667-
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
3668-
AccessPath ap, Configuration config
3668+
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
3669+
DataFlowCall call, AccessPath ap, Configuration config
36693670
) {
36703671
exists(AccessPathApprox apa |
3671-
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
3672+
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
36723673
pragma[only_bind_into](config)) and
36733674
callable = resolveCall(call, outercc) and
3674-
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
3675+
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
36753676
pragma[only_bind_into](config))
36763677
)
36773678
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
36863687
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
36873688
DataFlowCall call, Configuration config
36883689
) {
3689-
exists(int i, DataFlowCallable callable, AccessPath ap |
3690-
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
3691-
p.isParameterOf(callable, i) and
3690+
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
3691+
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
3692+
p.isParameterOf(callable, pos) and
36923693
(
36933694
sc = TSummaryCtxSome(p, ap)
36943695
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
37123713
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
37133714
Configuration config
37143715
) {
3715-
exists(PathNodeMid mid, RetNodeEx ret, int pos |
3716+
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
37163717
mid.getNodeEx() = ret and
37173718
kind = ret.getKind() and
37183719
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
44414442

44424443
pragma[noinline]
44434444
private predicate partialPathIntoArg(
4444-
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
4445-
Configuration config
4445+
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
4446+
PartialAccessPath ap, Configuration config
44464447
) {
4447-
exists(ArgNode arg |
4448+
exists(ArgNode arg, ArgumentPosition apos |
44484449
arg = mid.getNodeEx().asNode() and
44494450
cc = mid.getCallContext() and
4450-
arg.argumentOf(call, i) and
4451+
arg.argumentOf(call, apos) and
44514452
ap = mid.getAp() and
4452-
config = mid.getConfiguration()
4453+
config = mid.getConfiguration() and
4454+
parameterMatch(ppos, apos)
44534455
)
44544456
}
44554457

44564458
pragma[nomagic]
44574459
private predicate partialPathIntoCallable0(
4458-
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
4460+
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
44594461
DataFlowCall call, PartialAccessPath ap, Configuration config
44604462
) {
4461-
partialPathIntoArg(mid, i, outercc, call, ap, config) and
4463+
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
44624464
callable = resolveCall(call, outercc)
44634465
}
44644466

@@ -4467,9 +4469,9 @@ private module FlowExploration {
44674469
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
44684470
Configuration config
44694471
) {
4470-
exists(int i, DataFlowCallable callable |
4471-
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
4472-
p.isParameterOf(callable, i) and
4472+
exists(ParameterPosition pos, DataFlowCallable callable |
4473+
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
4474+
p.isParameterOf(callable, pos) and
44734475
sc1 = TSummaryCtx1Param(p) and
44744476
sc2 = TSummaryCtx2Some(ap)
44754477
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
46334635

46344636
pragma[nomagic]
46354637
private predicate revPartialPathFlowsThrough(
4636-
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
4637-
Configuration config
4638+
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
4639+
RevPartialAccessPath ap, Configuration config
46384640
) {
4639-
exists(PartialPathNodeRev mid, ParamNodeEx p |
4641+
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
46404642
mid.getNodeEx() = p and
4641-
p.getPosition() = pos and
4643+
p.getPosition() = ppos and
46424644
sc1 = mid.getSummaryCtx1() and
46434645
sc2 = mid.getSummaryCtx2() and
46444646
ap = mid.getAp() and
4645-
config = mid.getConfiguration()
4647+
config = mid.getConfiguration() and
4648+
parameterMatch(ppos, apos)
46464649
)
46474650
}
46484651

46494652
pragma[nomagic]
46504653
private predicate revPartialPathThroughCallable0(
4651-
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
4654+
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
46524655
Configuration config
46534656
) {
46544657
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
46614664
private predicate revPartialPathThroughCallable(
46624665
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
46634666
) {
4664-
exists(DataFlowCall call, int pos |
4667+
exists(DataFlowCall call, ArgumentPosition pos |
46654668
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
46664669
node.asNode().(ArgNode).argumentOf(call, pos)
46674670
)

0 commit comments

Comments
 (0)