Skip to content

Commit c70d384

Browse files
authored
Merge pull request #7045 from aschackmull/dataflow/hidden-ret-subpaths
Data flow: Support hidden return nodes in subpaths predicate
2 parents a65f572 + 7ffd9b4 commit c70d384

File tree

35 files changed

+553
-245
lines changed

35 files changed

+553
-245
lines changed

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

0 commit comments

Comments
 (0)