Skip to content

Commit fc5158c

Browse files
authored
Merge pull request github#5338 from hvitved/dataflow/performance-tweaks
Data flow: Performance tweaks
2 parents ed250d5 + fe6efde commit fc5158c

28 files changed

+1074
-1216
lines changed

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

Lines changed: 43 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,6 @@ private predicate fullBarrier(Node node, Configuration config) {
207207
)
208208
}
209209

210-
private class AdditionalFlowStepSource extends Node {
211-
AdditionalFlowStepSource() { any(Configuration c).isAdditionalFlowStep(this, _) }
212-
}
213-
214-
pragma[noinline]
215-
private predicate isAdditionalFlowStep(
216-
AdditionalFlowStepSource node1, Node node2, DataFlowCallable callable1, Configuration config
217-
) {
218-
config.isAdditionalFlowStep(node1, node2) and
219-
callable1 = node1.getEnclosingCallable()
220-
}
221-
222210
/**
223211
* Holds if data can flow in one local step from `node1` to `node2`.
224212
*/
@@ -237,7 +225,8 @@ private predicate localFlowStep(Node node1, Node node2, Configuration config) {
237225
* Holds if the additional step from `node1` to `node2` does not jump between callables.
238226
*/
239227
private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration config) {
240-
isAdditionalFlowStep(node1, node2, node2.getEnclosingCallable(), config) and
228+
config.isAdditionalFlowStep(node1, node2) and
229+
getNodeEnclosingCallable(node1) = getNodeEnclosingCallable(node2) and
241230
not outBarrier(node1, config) and
242231
not inBarrier(node2, config) and
243232
not fullBarrier(node1, config) and
@@ -259,14 +248,12 @@ private predicate jumpStep(Node node1, Node node2, Configuration config) {
259248
* Holds if the additional step from `node1` to `node2` jumps between callables.
260249
*/
261250
private predicate additionalJumpStep(Node node1, Node node2, Configuration config) {
262-
exists(DataFlowCallable callable1 |
263-
isAdditionalFlowStep(node1, node2, callable1, config) and
264-
node2.getEnclosingCallable() != callable1 and
265-
not outBarrier(node1, config) and
266-
not inBarrier(node2, config) and
267-
not fullBarrier(node1, config) and
268-
not fullBarrier(node2, config)
269-
)
251+
config.isAdditionalFlowStep(node1, node2) and
252+
getNodeEnclosingCallable(node1) != getNodeEnclosingCallable(node2) and
253+
not outBarrier(node1, config) and
254+
not inBarrier(node2, config) and
255+
not fullBarrier(node1, config) and
256+
not fullBarrier(node2, config)
270257
}
271258

272259
/**
@@ -601,7 +588,7 @@ private module Stage1 {
601588
) {
602589
exists(ReturnNodeExt ret |
603590
throughFlowNodeCand(ret, config) and
604-
callable = ret.getEnclosingCallable() and
591+
callable = getNodeEnclosingCallable(ret) and
605592
kind = ret.getKind()
606593
)
607594
}
@@ -614,7 +601,7 @@ private module Stage1 {
614601
exists(ReturnKindExt kind |
615602
throughFlowNodeCand(p, config) and
616603
returnFlowCallableNodeCand(c, kind, config) and
617-
p.getEnclosingCallable() = c and
604+
getNodeEnclosingCallable(p) = c and
618605
exists(ap) and
619606
// we don't expect a parameter to return stored in itself
620607
not exists(int pos |
@@ -778,7 +765,7 @@ private module Stage2 {
778765
bindingset[result, ap]
779766
private ApApprox getApprox(Ap ap) { any() }
780767

781-
private ApNil getApNil(Node node) { any() }
768+
private ApNil getApNil(Node node) { PrevStage::revFlow(node, _) and exists(result) }
782769

783770
bindingset[tc, tail]
784771
private Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) }
@@ -966,7 +953,7 @@ private module Stage2 {
966953
exists(ArgumentNode arg, boolean allowsFieldFlow |
967954
fwdFlow(arg, outercc, argAp, ap, config) and
968955
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
969-
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
956+
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
970957
|
971958
ap instanceof ApNil or allowsFieldFlow = true
972959
)
@@ -985,7 +972,7 @@ private module Stage2 {
985972
exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner |
986973
fwdFlow(ret, innercc, argAp, ap, config) and
987974
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
988-
inner = ret.getEnclosingCallable() and
975+
inner = getNodeEnclosingCallable(ret) and
989976
checkCallContextReturn(innercc, inner, call) and
990977
ccOut = getCallContextReturn(inner, call)
991978
|
@@ -1216,13 +1203,13 @@ private module Stage2 {
12161203
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
12171204
) {
12181205
revFlow(p, true, apSome(ap0), ap, config) and
1219-
c = p.getEnclosingCallable()
1206+
c = getNodeEnclosingCallable(p)
12201207
}
12211208

12221209
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
12231210
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
12241211
parameterFlow(p, ap, ap0, c, config) and
1225-
c = ret.getEnclosingCallable() and
1212+
c = getNodeEnclosingCallable(ret) and
12261213
revFlow(ret, true, apSome(_), ap0, config) and
12271214
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
12281215
kind = ret.getKind() and
@@ -1348,7 +1335,7 @@ private module LocalFlowBigStep {
13481335
t = getNodeType(node2)
13491336
) and
13501337
node1 != node2 and
1351-
cc.relevantFor(node1.getEnclosingCallable()) and
1338+
cc.relevantFor(getNodeEnclosingCallable(node1)) and
13521339
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
13531340
Stage2::revFlow(node2, unbind(config))
13541341
or
@@ -1397,7 +1384,9 @@ private module Stage3 {
13971384

13981385
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
13991386

1400-
private ApNil getApNil(Node node) { result = TFrontNil(getNodeType(node)) }
1387+
private ApNil getApNil(Node node) {
1388+
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
1389+
}
14011390

14021391
bindingset[tc, tail]
14031392
private Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) }
@@ -1594,7 +1583,7 @@ private module Stage3 {
15941583
exists(ArgumentNode arg, boolean allowsFieldFlow |
15951584
fwdFlow(arg, outercc, argAp, ap, config) and
15961585
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
1597-
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
1586+
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
15981587
|
15991588
ap instanceof ApNil or allowsFieldFlow = true
16001589
)
@@ -1613,7 +1602,7 @@ private module Stage3 {
16131602
exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner |
16141603
fwdFlow(ret, innercc, argAp, ap, config) and
16151604
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
1616-
inner = ret.getEnclosingCallable() and
1605+
inner = getNodeEnclosingCallable(ret) and
16171606
checkCallContextReturn(innercc, inner, call) and
16181607
ccOut = getCallContextReturn(inner, call)
16191608
|
@@ -1844,13 +1833,13 @@ private module Stage3 {
18441833
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
18451834
) {
18461835
revFlow(p, true, apSome(ap0), ap, config) and
1847-
c = p.getEnclosingCallable()
1836+
c = getNodeEnclosingCallable(p)
18481837
}
18491838

18501839
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
18511840
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
18521841
parameterFlow(p, ap, ap0, c, config) and
1853-
c = ret.getEnclosingCallable() and
1842+
c = getNodeEnclosingCallable(ret) and
18541843
revFlow(ret, true, apSome(_), ap0, config) and
18551844
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
18561845
kind = ret.getKind() and
@@ -2090,7 +2079,9 @@ private module Stage4 {
20902079

20912080
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
20922081

2093-
private ApNil getApNil(Node node) { result = TNil(getNodeType(node)) }
2082+
private ApNil getApNil(Node node) {
2083+
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
2084+
}
20942085

20952086
bindingset[tc, tail]
20962087
private Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) }
@@ -2135,7 +2126,7 @@ private module Stage4 {
21352126
bindingset[node, cc, config]
21362127
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
21372128
localFlowEntry(node, config) and
2138-
result = getLocalCallContext(cc, node.getEnclosingCallable())
2129+
result = getLocalCallContext(cc, getNodeEnclosingCallable(node))
21392130
}
21402131

21412132
private predicate localStep(
@@ -2300,7 +2291,7 @@ private module Stage4 {
23002291
exists(ArgumentNode arg, boolean allowsFieldFlow |
23012292
fwdFlow(arg, outercc, argAp, ap, config) and
23022293
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
2303-
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
2294+
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
23042295
|
23052296
ap instanceof ApNil or allowsFieldFlow = true
23062297
)
@@ -2319,7 +2310,7 @@ private module Stage4 {
23192310
exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner |
23202311
fwdFlow(ret, innercc, argAp, ap, config) and
23212312
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
2322-
inner = ret.getEnclosingCallable() and
2313+
inner = getNodeEnclosingCallable(ret) and
23232314
checkCallContextReturn(innercc, inner, call) and
23242315
ccOut = getCallContextReturn(inner, call)
23252316
|
@@ -2550,13 +2541,13 @@ private module Stage4 {
25502541
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
25512542
) {
25522543
revFlow(p, true, apSome(ap0), ap, config) and
2553-
c = p.getEnclosingCallable()
2544+
c = getNodeEnclosingCallable(p)
25542545
}
25552546

25562547
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
25572548
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
25582549
parameterFlow(p, ap, ap0, c, config) and
2559-
c = ret.getEnclosingCallable() and
2550+
c = getNodeEnclosingCallable(ret) and
25602551
revFlow(ret, true, apSome(_), ap0, config) and
25612552
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
25622553
kind = ret.getKind() and
@@ -2590,7 +2581,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
25902581
Stage4::parameterMayFlowThrough(_, c, apa, _) and
25912582
Stage4::revFlow(n, true, _, apa0, config) and
25922583
Stage4::fwdFlow(n, any(CallContextCall ccc), TAccessPathApproxSome(apa), apa0, config) and
2593-
n.getEnclosingCallable() = c
2584+
getNodeEnclosingCallable(n) = c
25942585
)
25952586
}
25962587

@@ -3119,7 +3110,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
31193110
conf = mid.getConfiguration() and
31203111
cc = mid.getCallContext() and
31213112
sc = mid.getSummaryCtx() and
3122-
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
3113+
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
31233114
ap0 = mid.getAp()
31243115
|
31253116
localFlowBigStep(midnode, node, true, _, conf, localCC) and
@@ -3405,22 +3396,22 @@ private module FlowExploration {
34053396
// flow out of a callable
34063397
viableReturnPosOut(_, getReturnPosition(node1), node2)
34073398
|
3408-
c1 = node1.getEnclosingCallable() and
3409-
c2 = node2.getEnclosingCallable() and
3399+
c1 = getNodeEnclosingCallable(node1) and
3400+
c2 = getNodeEnclosingCallable(node2) and
34103401
c1 != c2
34113402
)
34123403
}
34133404

34143405
private predicate interestingCallableSrc(DataFlowCallable c, Configuration config) {
3415-
exists(Node n | config.isSource(n) and c = n.getEnclosingCallable())
3406+
exists(Node n | config.isSource(n) and c = getNodeEnclosingCallable(n))
34163407
or
34173408
exists(DataFlowCallable mid |
34183409
interestingCallableSrc(mid, config) and callableStep(mid, c, config)
34193410
)
34203411
}
34213412

34223413
private predicate interestingCallableSink(DataFlowCallable c, Configuration config) {
3423-
exists(Node n | config.isSink(n) and c = n.getEnclosingCallable())
3414+
exists(Node n | config.isSink(n) and c = getNodeEnclosingCallable(n))
34243415
or
34253416
exists(DataFlowCallable mid |
34263417
interestingCallableSink(mid, config) and callableStep(c, mid, config)
@@ -3449,13 +3440,13 @@ private module FlowExploration {
34493440
exists(Node n, Configuration config |
34503441
ce1 = TCallableSrc() and
34513442
config.isSource(n) and
3452-
ce2 = TCallable(n.getEnclosingCallable(), config)
3443+
ce2 = TCallable(getNodeEnclosingCallable(n), config)
34533444
)
34543445
or
34553446
exists(Node n, Configuration config |
34563447
ce2 = TCallableSink() and
34573448
config.isSink(n) and
3458-
ce1 = TCallable(n.getEnclosingCallable(), config)
3449+
ce1 = TCallable(getNodeEnclosingCallable(n), config)
34593450
)
34603451
}
34613452

@@ -3586,7 +3577,7 @@ private module FlowExploration {
35863577
exists(config.explorationLimit())
35873578
or
35883579
partialPathNodeMk0(node, cc, sc1, sc2, ap, config) and
3589-
distSrc(node.getEnclosingCallable(), config) <= config.explorationLimit()
3580+
distSrc(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
35903581
} or
35913582
TPartialPathNodeRev(
35923583
Node node, TRevSummaryCtx1 sc1, TRevSummaryCtx2 sc2, RevPartialAccessPath ap,
@@ -3603,7 +3594,7 @@ private module FlowExploration {
36033594
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
36043595
not clearsContent(node, ap.getHead()) and
36053596
not fullBarrier(node, config) and
3606-
distSink(node.getEnclosingCallable(), config) <= config.explorationLimit()
3597+
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
36073598
)
36083599
}
36093600

@@ -3662,15 +3653,15 @@ private module FlowExploration {
36623653
* of interprocedural steps.
36633654
*/
36643655
int getSourceDistance() {
3665-
result = distSrc(this.getNode().getEnclosingCallable(), this.getConfiguration())
3656+
result = distSrc(getNodeEnclosingCallable(this.getNode()), this.getConfiguration())
36663657
}
36673658

36683659
/**
36693660
* Gets the approximate distance to the nearest sink measured in number
36703661
* of interprocedural steps.
36713662
*/
36723663
int getSinkDistance() {
3673-
result = distSink(this.getNode().getEnclosingCallable(), this.getConfiguration())
3664+
result = distSink(getNodeEnclosingCallable(this.getNode()), this.getConfiguration())
36743665
}
36753666

36763667
private string ppAp() {

0 commit comments

Comments
 (0)