Skip to content

Commit cae7f9d

Browse files
authored
Merge pull request #2099 from aschackmull/java/callcontext-bool-pruning
Java: Data-flow pruning based on call contexts.
2 parents 527ec4a + 2be5c38 commit cae7f9d

33 files changed

+2085
-1111
lines changed

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

Lines changed: 67 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -905,42 +905,47 @@ private predicate localFlowExit(Node node, Configuration config) {
905905
*/
906906
pragma[nomagic]
907907
private predicate localFlowStepPlus(
908-
Node node1, Node node2, boolean preservesValue, Configuration config
908+
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext cc
909909
) {
910-
localFlowEntry(node1, config) and
910+
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
911911
(
912-
localFlowStep(node1, node2, config) and preservesValue = true
913-
or
914-
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
915-
) and
916-
node1 != node2 and
917-
nodeCand(node2, unbind(config))
918-
or
919-
exists(Node mid |
920-
localFlowStepPlus(node1, mid, preservesValue, config) and
921-
localFlowStep(mid, node2, config) and
922-
not mid instanceof CastNode and
923-
nodeCand(node2, unbind(config))
924-
)
925-
or
926-
exists(Node mid |
927-
localFlowStepPlus(node1, mid, _, config) and
928-
additionalLocalFlowStep(mid, node2, config) and
929-
not mid instanceof CastNode and
930-
preservesValue = false and
912+
localFlowEntry(node1, config) and
913+
(
914+
localFlowStep(node1, node2, config) and preservesValue = true
915+
or
916+
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
917+
) and
918+
node1 != node2 and
919+
cc.relevantFor(node1.getEnclosingCallable()) and
920+
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
931921
nodeCand(node2, unbind(config))
922+
or
923+
exists(Node mid |
924+
localFlowStepPlus(node1, mid, preservesValue, config, cc) and
925+
localFlowStep(mid, node2, config) and
926+
not mid instanceof CastNode and
927+
nodeCand(node2, unbind(config))
928+
)
929+
or
930+
exists(Node mid |
931+
localFlowStepPlus(node1, mid, _, config, cc) and
932+
additionalLocalFlowStep(mid, node2, config) and
933+
not mid instanceof CastNode and
934+
preservesValue = false and
935+
nodeCand(node2, unbind(config))
936+
)
932937
)
933938
}
934939

935940
/**
936941
* Holds if `node1` can step to `node2` in one or more local steps and this
937942
* path can occur as a maximal subsequence of local steps in a dataflow path.
938943
*/
939-
pragma[noinline]
944+
pragma[nomagic]
940945
private predicate localFlowBigStep(
941-
Node node1, Node node2, boolean preservesValue, Configuration config
946+
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext callContext
942947
) {
943-
localFlowStepPlus(node1, node2, preservesValue, config) and
948+
localFlowStepPlus(node1, node2, preservesValue, config, callContext) and
944949
localFlowExit(node2, config)
945950
}
946951

@@ -1000,7 +1005,7 @@ private class AccessPathFrontNilNode extends Node {
10001005
(
10011006
any(Configuration c).isSource(this)
10021007
or
1003-
localFlowBigStep(_, this, false, _)
1008+
localFlowBigStep(_, this, false, _, _)
10041009
or
10051010
additionalJumpStep(_, this, _)
10061011
)
@@ -1023,12 +1028,12 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
10231028
(
10241029
exists(Node mid |
10251030
flowCandFwd(mid, fromArg, apf, config) and
1026-
localFlowBigStep(mid, node, true, config)
1031+
localFlowBigStep(mid, node, true, config, _)
10271032
)
10281033
or
10291034
exists(Node mid, AccessPathFrontNil nil |
10301035
flowCandFwd(mid, fromArg, nil, config) and
1031-
localFlowBigStep(mid, node, false, config) and
1036+
localFlowBigStep(mid, node, false, config, _) and
10321037
apf = node.(AccessPathFrontNilNode).getApf()
10331038
)
10341039
or
@@ -1122,13 +1127,13 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
11221127
apf instanceof AccessPathFrontNil
11231128
or
11241129
exists(Node mid |
1125-
localFlowBigStep(node, mid, true, config) and
1130+
localFlowBigStep(node, mid, true, config, _) and
11261131
flowCand(mid, toReturn, apf, config)
11271132
)
11281133
or
11291134
exists(Node mid, AccessPathFrontNil nil |
11301135
flowCandFwd(node, _, apf, config) and
1131-
localFlowBigStep(node, mid, false, config) and
1136+
localFlowBigStep(node, mid, false, config, _) and
11321137
flowCand(mid, toReturn, nil, config) and
11331138
apf instanceof AccessPathFrontNil
11341139
)
@@ -1363,12 +1368,12 @@ private predicate flowFwd0(
13631368
(
13641369
exists(Node mid |
13651370
flowFwd(mid, fromArg, apf, ap, config) and
1366-
localFlowBigStep(mid, node, true, config)
1371+
localFlowBigStep(mid, node, true, config, _)
13671372
)
13681373
or
13691374
exists(Node mid, AccessPathNil nil |
13701375
flowFwd(mid, fromArg, _, nil, config) and
1371-
localFlowBigStep(mid, node, false, config) and
1376+
localFlowBigStep(mid, node, false, config, _) and
13721377
ap = node.(AccessPathNilNode).getAp() and
13731378
apf = ap.(AccessPathNil).getFront()
13741379
)
@@ -1472,13 +1477,13 @@ private predicate flow0(Node node, boolean toReturn, AccessPath ap, Configuratio
14721477
ap instanceof AccessPathNil
14731478
or
14741479
exists(Node mid |
1475-
localFlowBigStep(node, mid, true, config) and
1480+
localFlowBigStep(node, mid, true, config, _) and
14761481
flow(mid, toReturn, ap, config)
14771482
)
14781483
or
14791484
exists(Node mid, AccessPathNil nil |
14801485
flowFwd(node, _, _, ap, config) and
1481-
localFlowBigStep(node, mid, false, config) and
1486+
localFlowBigStep(node, mid, false, config, _) and
14821487
flow(mid, toReturn, nil, config) and
14831488
ap instanceof AccessPathNil
14841489
)
@@ -1729,14 +1734,20 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
17291734
* a callable is recorded by `cc`.
17301735
*/
17311736
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPath ap) {
1732-
localFlowBigStep(mid.getNode(), node, true, mid.getConfiguration()) and
1733-
cc = mid.getCallContext() and
1734-
ap = mid.getAp()
1735-
or
1736-
localFlowBigStep(mid.getNode(), node, false, mid.getConfiguration()) and
1737-
cc = mid.getCallContext() and
1738-
mid.getAp() instanceof AccessPathNil and
1739-
ap = node.(AccessPathNilNode).getAp()
1737+
exists(LocalCallContext localCC, AccessPath ap0, Node midnode, Configuration conf |
1738+
midnode = mid.getNode() and
1739+
conf = mid.getConfiguration() and
1740+
cc = mid.getCallContext() and
1741+
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
1742+
ap0 = mid.getAp()
1743+
|
1744+
localFlowBigStep(midnode, node, true, conf, localCC) and
1745+
ap = ap0
1746+
or
1747+
localFlowBigStep(midnode, node, false, conf, localCC) and
1748+
ap0 instanceof AccessPathNil and
1749+
ap = node.(AccessPathNilNode).getAp()
1750+
)
17401751
or
17411752
jumpStep(mid.getNode(), node, mid.getConfiguration()) and
17421753
cc instanceof CallContextAny and
@@ -1880,7 +1891,7 @@ private predicate pathIntoCallable(
18801891
pathIntoCallable0(mid, callable, i, outercc, call, emptyAp) and
18811892
p.isParameterOf(callable, i)
18821893
|
1883-
if reducedViableImplInCallContext(_, callable, call)
1894+
if recordDataFlowCallSite(call, callable)
18841895
then innercc = TSpecificCall(call, i, emptyAp)
18851896
else innercc = TSomeCall(p, emptyAp)
18861897
)
@@ -2205,16 +2216,19 @@ private module FlowExploration {
22052216
private predicate partialPathStep(
22062217
PartialPathNodePriv mid, Node node, CallContext cc, PartialAccessPath ap, Configuration config
22072218
) {
2208-
localFlowStep(mid.getNode(), node, config) and
2209-
cc = mid.getCallContext() and
2210-
ap = mid.getAp() and
2211-
config = mid.getConfiguration()
2212-
or
2213-
additionalLocalFlowStep(mid.getNode(), node, config) and
2214-
cc = mid.getCallContext() and
2215-
mid.getAp() instanceof PartialAccessPathNil and
2216-
ap = TPartialNil(getErasedRepr(node.getType())) and
2217-
config = mid.getConfiguration()
2219+
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
2220+
(
2221+
localFlowStep(mid.getNode(), node, config) and
2222+
cc = mid.getCallContext() and
2223+
ap = mid.getAp() and
2224+
config = mid.getConfiguration()
2225+
or
2226+
additionalLocalFlowStep(mid.getNode(), node, config) and
2227+
cc = mid.getCallContext() and
2228+
mid.getAp() instanceof PartialAccessPathNil and
2229+
ap = TPartialNil(getErasedRepr(node.getType())) and
2230+
config = mid.getConfiguration()
2231+
)
22182232
or
22192233
jumpStep(mid.getNode(), node, config) and
22202234
cc instanceof CallContextAny and
@@ -2378,7 +2392,7 @@ private module FlowExploration {
23782392
partialPathIntoCallable0(mid, callable, i, outercc, call, emptyAp, ap, config) and
23792393
p.isParameterOf(callable, i)
23802394
|
2381-
if reducedViableImplInCallContext(_, callable, call)
2395+
if recordDataFlowCallSite(call, callable)
23822396
then innercc = TSpecificCall(call, i, emptyAp)
23832397
else innercc = TSomeCall(p, emptyAp)
23842398
)

0 commit comments

Comments
 (0)