Skip to content

Commit bd6c23d

Browse files
authored
Merge pull request github#3020 from aschackmull/dataflow/type-pruning-bigstep
Dataflow: Fix bug in type pruning.
2 parents 570f095 + fc87f1e commit bd6c23d

File tree

25 files changed

+791
-1296
lines changed

25 files changed

+791
-1296
lines changed

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

Lines changed: 34 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,33 +1307,39 @@ private predicate localFlowExit(Node node, Configuration config) {
13071307
*/
13081308
pragma[nomagic]
13091309
private predicate localFlowStepPlus(
1310-
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext cc
1310+
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
1311+
LocalCallContext cc
13111312
) {
13121313
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
13131314
(
13141315
localFlowEntry(node1, config) and
13151316
(
1316-
localFlowStep(node1, node2, config) and preservesValue = true
1317+
localFlowStep(node1, node2, config) and
1318+
preservesValue = true and
1319+
t = getErasedNodeTypeBound(node1)
13171320
or
1318-
additionalLocalFlowStep(node1, node2, config) and preservesValue = false
1321+
additionalLocalFlowStep(node1, node2, config) and
1322+
preservesValue = false and
1323+
t = getErasedNodeTypeBound(node2)
13191324
) and
13201325
node1 != node2 and
13211326
cc.relevantFor(node1.getEnclosingCallable()) and
13221327
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
13231328
nodeCand(TNormalNode(node2), unbind(config))
13241329
or
13251330
exists(Node mid |
1326-
localFlowStepPlus(node1, mid, preservesValue, config, cc) and
1331+
localFlowStepPlus(node1, mid, preservesValue, t, config, cc) and
13271332
localFlowStep(mid, node2, config) and
13281333
not mid instanceof CastNode and
13291334
nodeCand(TNormalNode(node2), unbind(config))
13301335
)
13311336
or
13321337
exists(Node mid |
1333-
localFlowStepPlus(node1, mid, _, config, cc) and
1338+
localFlowStepPlus(node1, mid, _, _, config, cc) and
13341339
additionalLocalFlowStep(mid, node2, config) and
13351340
not mid instanceof CastNode and
13361341
preservesValue = false and
1342+
t = getErasedNodeTypeBound(node2) and
13371343
nodeCand(TNormalNode(node2), unbind(config))
13381344
)
13391345
)
@@ -1345,17 +1351,18 @@ private predicate localFlowStepPlus(
13451351
*/
13461352
pragma[nomagic]
13471353
private predicate localFlowBigStep(
1348-
Node node1, Node node2, boolean preservesValue, Configuration config, LocalCallContext callContext
1354+
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
1355+
LocalCallContext callContext
13491356
) {
1350-
localFlowStepPlus(node1, node2, preservesValue, config, callContext) and
1357+
localFlowStepPlus(node1, node2, preservesValue, t, config, callContext) and
13511358
localFlowExit(node2, config)
13521359
}
13531360

13541361
pragma[nomagic]
13551362
private predicate localFlowBigStepExt(
1356-
NodeExt node1, NodeExt node2, boolean preservesValue, Configuration config
1363+
NodeExt node1, NodeExt node2, boolean preservesValue, AccessPathFrontNil apf, Configuration config
13571364
) {
1358-
localFlowBigStep(node1.getNode(), node2.getNode(), preservesValue, config, _)
1365+
localFlowBigStep(node1.getNode(), node2.getNode(), preservesValue, apf.getType(), config, _)
13591366
}
13601367

13611368
private newtype TAccessPathFront =
@@ -1395,46 +1402,24 @@ private predicate flowCandFwd(
13951402
else any()
13961403
}
13971404

1398-
/**
1399-
* A node that requires an empty access path and should have its tracked type
1400-
* (re-)computed. This is either a source or a node reached through an
1401-
* additional step.
1402-
*/
1403-
private class AccessPathFrontNilNode extends NormalNodeExt {
1404-
AccessPathFrontNilNode() {
1405-
nodeCand(this, _) and
1406-
(
1407-
any(Configuration c).isSource(this.getNode())
1408-
or
1409-
localFlowBigStepExt(_, this, false, _)
1410-
or
1411-
additionalJumpStepExt(_, this, _)
1412-
)
1413-
}
1414-
1415-
/** Gets the `nil` path front for this node. */
1416-
AccessPathFrontNil getApf() { result = TFrontNil(this.getErasedNodeTypeBound()) }
1417-
}
1418-
14191405
private predicate flowCandFwd0(
14201406
NodeExt node, boolean fromArg, AccessPathFront apf, Configuration config
14211407
) {
14221408
nodeCand2(node, _, false, config) and
14231409
config.isSource(node.getNode()) and
14241410
fromArg = false and
1425-
apf = node.(AccessPathFrontNilNode).getApf()
1411+
apf = TFrontNil(node.getErasedNodeTypeBound())
14261412
or
14271413
nodeCand(node, unbind(config)) and
14281414
(
14291415
exists(NodeExt mid |
14301416
flowCandFwd(mid, fromArg, apf, config) and
1431-
localFlowBigStepExt(mid, node, true, config)
1417+
localFlowBigStepExt(mid, node, true, _, config)
14321418
)
14331419
or
14341420
exists(NodeExt mid, AccessPathFrontNil nil |
14351421
flowCandFwd(mid, fromArg, nil, config) and
1436-
localFlowBigStepExt(mid, node, false, config) and
1437-
apf = node.(AccessPathFrontNilNode).getApf()
1422+
localFlowBigStepExt(mid, node, false, apf, config)
14381423
)
14391424
or
14401425
exists(NodeExt mid |
@@ -1447,7 +1432,7 @@ private predicate flowCandFwd0(
14471432
flowCandFwd(mid, _, nil, config) and
14481433
additionalJumpStepExt(mid, node, config) and
14491434
fromArg = false and
1450-
apf = node.(AccessPathFrontNilNode).getApf()
1435+
apf = TFrontNil(node.getErasedNodeTypeBound())
14511436
)
14521437
or
14531438
exists(NodeExt mid, boolean allowsFieldFlow |
@@ -1589,13 +1574,13 @@ private predicate flowCand0(
15891574
apf instanceof AccessPathFrontNil
15901575
or
15911576
exists(NodeExt mid |
1592-
localFlowBigStepExt(node, mid, true, config) and
1577+
localFlowBigStepExt(node, mid, true, _, config) and
15931578
flowCand(mid, toReturn, apf, config)
15941579
)
15951580
or
15961581
exists(NodeExt mid, AccessPathFrontNil nil |
15971582
flowCandFwd(node, _, apf, config) and
1598-
localFlowBigStepExt(node, mid, false, config) and
1583+
localFlowBigStepExt(node, mid, false, _, config) and
15991584
flowCand(mid, toReturn, nil, config) and
16001585
apf instanceof AccessPathFrontNil
16011586
)
@@ -1810,18 +1795,6 @@ private predicate popWithFront(AccessPath ap0, Content f, AccessPathFront apf, A
18101795
/** Gets the access path obtained by pushing `f` onto `ap`. */
18111796
private AccessPath push(Content f, AccessPath ap) { ap = pop(f, result) }
18121797

1813-
/**
1814-
* A node that requires an empty access path and should have its tracked type
1815-
* (re-)computed. This is either a source or a node reached through an
1816-
* additional step.
1817-
*/
1818-
private class AccessPathNilNode extends NormalNodeExt {
1819-
AccessPathNilNode() { flowCand(this.(AccessPathFrontNilNode), _, _, _) }
1820-
1821-
/** Gets the `nil` path for this node. */
1822-
AccessPathNil getAp() { result = TNil(this.getErasedNodeTypeBound()) }
1823-
}
1824-
18251798
/**
18261799
* Holds if data can flow from a source to `node` with the given `ap`.
18271800
*/
@@ -1838,20 +1811,19 @@ private predicate flowFwd0(
18381811
flowCand(node, _, _, config) and
18391812
config.isSource(node.getNode()) and
18401813
fromArg = false and
1841-
ap = node.(AccessPathNilNode).getAp() and
1814+
ap = TNil(node.getErasedNodeTypeBound()) and
18421815
apf = ap.(AccessPathNil).getFront()
18431816
or
18441817
flowCand(node, _, _, unbind(config)) and
18451818
(
18461819
exists(NodeExt mid |
18471820
flowFwd(mid, fromArg, apf, ap, config) and
1848-
localFlowBigStepExt(mid, node, true, config)
1821+
localFlowBigStepExt(mid, node, true, _, config)
18491822
)
18501823
or
18511824
exists(NodeExt mid, AccessPathNil nil |
18521825
flowFwd(mid, fromArg, _, nil, config) and
1853-
localFlowBigStepExt(mid, node, false, config) and
1854-
ap = node.(AccessPathNilNode).getAp() and
1826+
localFlowBigStepExt(mid, node, false, apf, config) and
18551827
apf = ap.(AccessPathNil).getFront()
18561828
)
18571829
or
@@ -1865,7 +1837,7 @@ private predicate flowFwd0(
18651837
flowFwd(mid, _, _, nil, config) and
18661838
additionalJumpStepExt(mid, node, config) and
18671839
fromArg = false and
1868-
ap = node.(AccessPathNilNode).getAp() and
1840+
ap = TNil(node.getErasedNodeTypeBound()) and
18691841
apf = ap.(AccessPathNil).getFront()
18701842
)
18711843
or
@@ -1982,13 +1954,13 @@ private predicate flow0(NodeExt node, boolean toReturn, AccessPath ap, Configura
19821954
ap instanceof AccessPathNil
19831955
or
19841956
exists(NodeExt mid |
1985-
localFlowBigStepExt(node, mid, true, config) and
1957+
localFlowBigStepExt(node, mid, true, _, config) and
19861958
flow(mid, toReturn, ap, config)
19871959
)
19881960
or
19891961
exists(NodeExt mid, AccessPathNil nil |
19901962
flowFwd(node, _, _, ap, config) and
1991-
localFlowBigStepExt(node, mid, false, config) and
1963+
localFlowBigStepExt(node, mid, false, _, config) and
19921964
flow(mid, toReturn, nil, config) and
19931965
ap instanceof AccessPathNil
19941966
)
@@ -2164,7 +2136,7 @@ private newtype TPathNode =
21642136
config.isSource(node) and
21652137
cc instanceof CallContextAny and
21662138
sc instanceof SummaryCtxNone and
2167-
ap = any(AccessPathNilNode nil | nil.getNode() = node).getAp()
2139+
ap = TNil(getErasedNodeTypeBound(node))
21682140
or
21692141
// ... or a step from an existing PathNode to another node.
21702142
exists(PathNodeMid mid |
@@ -2357,12 +2329,11 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
23572329
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
23582330
localCC = getLocalCallContext(cc, enclosing)
23592331
|
2360-
localFlowBigStep(midnode, node, true, conf, localCC) and
2332+
localFlowBigStep(midnode, node, true, _, conf, localCC) and
23612333
ap = ap0
23622334
or
2363-
localFlowBigStep(midnode, node, false, conf, localCC) and
2364-
ap0 instanceof AccessPathNil and
2365-
ap = any(AccessPathNilNode nil | nil.getNode() = node).getAp()
2335+
localFlowBigStep(midnode, node, false, ap.(AccessPathNil).getType(), conf, localCC) and
2336+
ap0 instanceof AccessPathNil
23662337
)
23672338
or
23682339
jumpStep(mid.getNode(), node, mid.getConfiguration()) and
@@ -2374,7 +2345,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
23742345
cc instanceof CallContextAny and
23752346
sc instanceof SummaryCtxNone and
23762347
mid.getAp() instanceof AccessPathNil and
2377-
ap = any(AccessPathNilNode nil | nil.getNode() = node).getAp()
2348+
ap = TNil(getErasedNodeTypeBound(node))
23782349
or
23792350
exists(Content f, AccessPath ap0 | pathReadStep(mid, node, ap0, f, cc) and ap = pop(f, ap0)) and
23802351
sc = mid.getSummaryCtx()
@@ -2397,7 +2368,7 @@ private predicate pathIntoLocalStep(
23972368
midnode = mid.getNode() and
23982369
cc = mid.getCallContext() and
23992370
conf = mid.getConfiguration() and
2400-
localFlowBigStep(midnode, _, _, conf, _) and
2371+
localFlowBigStep(midnode, _, _, _, conf, _) and
24012372
enclosing = midnode.getEnclosingCallable() and
24022373
sc = mid.getSummaryCtx() and
24032374
ap0 = mid.getAp()

0 commit comments

Comments
 (0)