Skip to content

Commit 140d0e2

Browse files
committed
Data flow: Cache TNodeEx
1 parent 6264059 commit 140d0e2

File tree

3 files changed

+159
-132
lines changed

3 files changed

+159
-132
lines changed

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

+9-96
Original file line numberDiff line numberDiff line change
@@ -153,94 +153,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
153153
module Impl<FullStateConfigSig Config> {
154154
private class FlowState = Config::FlowState;
155155

156-
private newtype TNodeEx =
157-
TNodeNormal(Node n) or
158-
TNodeImplicitRead(Node n) { Config::allowImplicitRead(n, _) } or
159-
TParamReturnNode(ParameterNode p, SndLevelScopeOption scope) {
160-
paramReturnNode(_, p, scope, _)
161-
}
162-
163-
private class NodeEx extends TNodeEx {
164-
string toString() {
165-
result = this.asNode().toString()
156+
private class NodeEx extends NodeExImpl {
157+
NodeEx() {
158+
Config::allowImplicitRead(any(Node n | this.isImplicitReadNode(n)), _)
166159
or
167-
exists(Node n | this.isImplicitReadNode(n) | result = n.toString() + " [Ext]")
168-
or
169-
result = this.asParamReturnNode().toString() + " [Return]"
170-
}
171-
172-
Node asNode() { this = TNodeNormal(result) }
173-
174-
/** Gets the corresponding Node if this is a normal node or its post-implicit read node. */
175-
Node asNodeOrImplicitRead() { this = TNodeNormal(result) or this = TNodeImplicitRead(result) }
176-
177-
predicate isImplicitReadNode(Node n) { this = TNodeImplicitRead(n) }
178-
179-
ParameterNode asParamReturnNode() { this = TParamReturnNode(result, _) }
180-
181-
Node projectToNode() {
182-
this = TNodeNormal(result) or
183-
this = TNodeImplicitRead(result) or
184-
this = TParamReturnNode(result, _)
185-
}
186-
187-
pragma[nomagic]
188-
private DataFlowCallable getEnclosingCallable0() {
189-
nodeEnclosingCallable(this.projectToNode(), result)
190-
}
191-
192-
pragma[inline]
193-
DataFlowCallable getEnclosingCallable() {
194-
pragma[only_bind_out](this).getEnclosingCallable0() = pragma[only_bind_into](result)
195-
}
196-
197-
pragma[nomagic]
198-
private DataFlowType getDataFlowType0() {
199-
nodeDataFlowType(this.asNode(), result)
200-
or
201-
nodeDataFlowType(this.asParamReturnNode(), result)
202-
}
203-
204-
pragma[inline]
205-
DataFlowType getDataFlowType() {
206-
pragma[only_bind_out](this).getDataFlowType0() = pragma[only_bind_into](result)
160+
not this.isImplicitReadNode(_)
207161
}
208-
209-
Location getLocation() { result = this.projectToNode().getLocation() }
210-
}
211-
212-
private class ArgNodeEx extends NodeEx {
213-
ArgNodeEx() { this.asNode() instanceof ArgNode }
214-
215-
DataFlowCall getCall() { this.asNode().(ArgNode).argumentOf(result, _) }
216-
}
217-
218-
private class ParamNodeEx extends NodeEx {
219-
ParamNodeEx() { this.asNode() instanceof ParamNode }
220-
221-
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
222-
this.asNode().(ParamNode).isParameterOf(c, pos)
223-
}
224-
225-
ParameterPosition getPosition() { this.isParameterOf(_, result) }
226162
}
227163

228-
/**
229-
* A node from which flow can return to the caller. This is either a regular
230-
* `ReturnNode` or a synthesized node for flow out via a parameter.
231-
*/
232-
private class RetNodeEx extends NodeEx {
233-
private ReturnPosition pos;
164+
private class ArgNodeEx extends NodeEx, ArgNodeExImpl { }
234165

235-
RetNodeEx() {
236-
pos = getValueReturnPosition(this.asNode()) or
237-
pos = getParamReturnPosition(_, this.asParamReturnNode())
238-
}
166+
private class ParamNodeEx extends NodeEx, ParamNodeExImpl { }
239167

240-
ReturnPosition getReturnPosition() { result = pos }
241-
242-
ReturnKindExt getKind() { result = pos.getKind() }
243-
}
168+
private class RetNodeEx extends NodeEx, RetNodeExImpl { }
244169

245170
/** If `node` corresponds to a sink, gets the normal node for that sink. */
246171
pragma[nomagic]
@@ -363,20 +288,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
363288
* Holds if data can flow in one local step from `node1` to `node2`.
364289
*/
365290
private predicate localFlowStepEx(NodeEx node1, NodeEx node2, string model) {
366-
exists(Node n1, Node n2 |
367-
node1.asNode() = n1 and
368-
node2.asNode() = n2 and
369-
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2), model) and
370-
stepFilter(node1, node2)
371-
)
372-
or
373-
exists(Node n1, Node n2, SndLevelScopeOption scope |
374-
node1.asNode() = n1 and
375-
node2 = TParamReturnNode(n2, scope) and
376-
paramReturnNode(pragma[only_bind_into](n1), pragma[only_bind_into](n2),
377-
pragma[only_bind_into](scope), _) and
378-
model = ""
379-
)
291+
localFlowStepExImpl(node1, node2, model) and
292+
stepFilter(node1, node2)
380293
}
381294

382295
/**

shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll

+149-35
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,85 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
850850

851851
class SndLevelScopeOption = SndLevelScopeOption::Option;
852852

853+
final class NodeExImpl extends TNodeEx {
854+
string toString() {
855+
result = this.asNode().toString()
856+
or
857+
exists(Node n | this.isImplicitReadNode(n) | result = n.toString() + " [Ext]")
858+
or
859+
result = this.asParamReturnNode().toString() + " [Return]"
860+
}
861+
862+
Node asNode() { this = TNodeNormal(result) }
863+
864+
/** Gets the corresponding Node if this is a normal node or its post-implicit read node. */
865+
Node asNodeOrImplicitRead() { this = TNodeNormal(result) or this = TNodeImplicitRead(result) }
866+
867+
predicate isImplicitReadNode(Node n) { this = TNodeImplicitRead(n) }
868+
869+
ParameterNode asParamReturnNode() { this = TParamReturnNode(result, _) }
870+
871+
Node projectToNode() {
872+
this = TNodeNormal(result) or
873+
this = TNodeImplicitRead(result) or
874+
this = TParamReturnNode(result, _)
875+
}
876+
877+
pragma[nomagic]
878+
private DataFlowCallable getEnclosingCallable0() {
879+
nodeEnclosingCallable(this.projectToNode(), result)
880+
}
881+
882+
pragma[inline]
883+
DataFlowCallable getEnclosingCallable() {
884+
pragma[only_bind_out](this).getEnclosingCallable0() = pragma[only_bind_into](result)
885+
}
886+
887+
pragma[nomagic]
888+
private DataFlowType getDataFlowType0() {
889+
nodeDataFlowType(this.asNode(), result)
890+
or
891+
nodeDataFlowType(this.asParamReturnNode(), result)
892+
}
893+
894+
pragma[inline]
895+
DataFlowType getDataFlowType() {
896+
pragma[only_bind_out](this).getDataFlowType0() = pragma[only_bind_into](result)
897+
}
898+
899+
Location getLocation() { result = this.projectToNode().getLocation() }
900+
}
901+
902+
final class ArgNodeExImpl extends NodeExImpl {
903+
ArgNodeExImpl() { this.asNode() instanceof ArgNode }
904+
905+
DataFlowCall getCall() { this.asNode().(ArgNode).argumentOf(result, _) }
906+
}
907+
908+
final class ParamNodeExImpl extends NodeExImpl {
909+
ParamNodeExImpl() { this.asNode() instanceof ParamNode }
910+
911+
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
912+
this.asNode().(ParamNode).isParameterOf(c, pos)
913+
}
914+
915+
ParameterPosition getPosition() { this.isParameterOf(_, result) }
916+
}
917+
918+
/**
919+
* A node from which flow can return to the caller. This is either a regular
920+
* `ReturnNode` or a synthesized node for flow out via a parameter.
921+
*/
922+
final class RetNodeExImpl extends NodeExImpl {
923+
private ReturnPosition pos;
924+
925+
RetNodeExImpl() { pos = getReturnPositionEx(this) }
926+
927+
ReturnPosition getReturnPosition() { result = pos }
928+
929+
ReturnKindExt getKind() { result = pos.getKind() }
930+
}
931+
853932
cached
854933
private module Cached {
855934
/**
@@ -927,11 +1006,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
9271006
)
9281007
}
9291008

930-
cached
931-
predicate valueReturnNode(ReturnNode n, ReturnKindExt k) { k = TValueReturn(n.getKind()) }
932-
933-
cached
934-
predicate paramReturnNode(
1009+
pragma[nomagic]
1010+
private predicate paramReturnNode(
9351011
PostUpdateNode n, ParamNode p, SndLevelScopeOption scope, ReturnKindExt k
9361012
) {
9371013
exists(ParameterPosition pos |
@@ -1541,6 +1617,20 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
15411617

15421618
class UnreachableSetOption = UnreachableSetOption::Option;
15431619

1620+
pragma[nomagic]
1621+
private predicate hasValueReturnKindIn(ReturnNode ret, ReturnKindExt kind, DataFlowCallable c) {
1622+
c = getNodeEnclosingCallable(ret) and
1623+
kind = TValueReturn(ret.getKind())
1624+
}
1625+
1626+
pragma[nomagic]
1627+
private predicate hasParamReturnKindIn(
1628+
PostUpdateNode n, ParamNode p, ReturnKindExt kind, DataFlowCallable c
1629+
) {
1630+
c = getNodeEnclosingCallable(n) and
1631+
paramReturnNode(n, p, _, kind)
1632+
}
1633+
15441634
cached
15451635
newtype TReturnPosition =
15461636
TReturnPosition0(DataFlowCallable c, ReturnKindExt kind) {
@@ -1549,6 +1639,22 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
15491639
hasParamReturnKindIn(_, _, kind, c)
15501640
}
15511641

1642+
cached
1643+
ReturnPosition getValueReturnPosition(ReturnNode ret) {
1644+
exists(ReturnKindExt kind, DataFlowCallable c |
1645+
hasValueReturnKindIn(ret, kind, c) and
1646+
result = TReturnPosition0(c, kind)
1647+
)
1648+
}
1649+
1650+
cached
1651+
ReturnPosition getParamReturnPosition(PostUpdateNode n, ParamNode p) {
1652+
exists(ReturnKindExt kind, DataFlowCallable c |
1653+
hasParamReturnKindIn(n, p, kind, c) and
1654+
result = TReturnPosition0(c, kind)
1655+
)
1656+
}
1657+
15521658
cached
15531659
newtype TLocalFlowCallContext =
15541660
TAnyLocalCall() or
@@ -1599,6 +1705,44 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
15991705
newtype TApproxAccessPathFrontOption =
16001706
TApproxAccessPathFrontNone() or
16011707
TApproxAccessPathFrontSome(ApproxAccessPathFront apf)
1708+
1709+
cached
1710+
newtype TNodeEx =
1711+
TNodeNormal(Node n) or
1712+
TNodeImplicitRead(Node n) or // will be restricted to nodes with actual implicit reads in `DataFlowImpl.qll`
1713+
TParamReturnNode(ParameterNode p, SndLevelScopeOption scope) {
1714+
paramReturnNode(_, p, scope, _)
1715+
}
1716+
1717+
/**
1718+
* Holds if data can flow in one local step from `node1` to `node2`.
1719+
*/
1720+
cached
1721+
predicate localFlowStepExImpl(NodeExImpl node1, NodeExImpl node2, string model) {
1722+
exists(Node n1, Node n2 |
1723+
node1.asNode() = n1 and
1724+
node2.asNode() = n2 and
1725+
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2), model)
1726+
)
1727+
or
1728+
exists(Node n1, Node n2, SndLevelScopeOption scope |
1729+
node1.asNode() = n1 and
1730+
node2 = TParamReturnNode(n2, scope) and
1731+
paramReturnNode(pragma[only_bind_into](n1), pragma[only_bind_into](n2),
1732+
pragma[only_bind_into](scope), _) and
1733+
model = ""
1734+
)
1735+
}
1736+
1737+
cached
1738+
ReturnPosition getReturnPositionEx(NodeExImpl ret) {
1739+
result = getValueReturnPosition(ret.asNode())
1740+
or
1741+
exists(ParamNode p |
1742+
ret = TParamReturnNode(p, _) and
1743+
result = getParamReturnPosition(_, p)
1744+
)
1745+
}
16021746
}
16031747

16041748
bindingset[call, tgt]
@@ -2182,36 +2326,6 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
21822326
nodeDataFlowType(pragma[only_bind_out](n), pragma[only_bind_into](result))
21832327
}
21842328

2185-
pragma[nomagic]
2186-
private predicate hasValueReturnKindIn(ReturnNode ret, ReturnKindExt kind, DataFlowCallable c) {
2187-
c = getNodeEnclosingCallable(ret) and
2188-
valueReturnNode(ret, kind)
2189-
}
2190-
2191-
pragma[nomagic]
2192-
private predicate hasParamReturnKindIn(
2193-
PostUpdateNode n, ParamNode p, ReturnKindExt kind, DataFlowCallable c
2194-
) {
2195-
c = getNodeEnclosingCallable(n) and
2196-
paramReturnNode(n, p, _, kind)
2197-
}
2198-
2199-
pragma[nomagic]
2200-
ReturnPosition getValueReturnPosition(ReturnNode ret) {
2201-
exists(ReturnKindExt kind, DataFlowCallable c |
2202-
hasValueReturnKindIn(ret, kind, c) and
2203-
result = TReturnPosition0(c, kind)
2204-
)
2205-
}
2206-
2207-
pragma[nomagic]
2208-
ReturnPosition getParamReturnPosition(PostUpdateNode n, ParamNode p) {
2209-
exists(ReturnKindExt kind, DataFlowCallable c |
2210-
hasParamReturnKindIn(n, p, kind, c) and
2211-
result = TReturnPosition0(c, kind)
2212-
)
2213-
}
2214-
22152329
/** An optional Boolean value. */
22162330
class BooleanOption extends TBooleanOption {
22172331
string toString() {

shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll

+1-1
Original file line numberDiff line numberDiff line change
@@ -1775,7 +1775,7 @@ module Make<
17751775
exists(ReturnNode ret, ValueReturnKind kind |
17761776
c = "ReturnValue" and
17771777
ret = node.asNode() and
1778-
valueReturnNode(ret, kind) and
1778+
kind.getKind() = ret.getKind() and
17791779
kind.getKind() = getStandardReturnValueKind() and
17801780
mid.asCallable() = getNodeEnclosingCallable(ret)
17811781
)

0 commit comments

Comments
 (0)