Skip to content

Commit 8c23e21

Browse files
committed
Dataflow: Cache compatibleTypes.
1 parent 06a7e3f commit 8c23e21

File tree

11 files changed

+41
-46
lines changed

11 files changed

+41
-46
lines changed

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ predicate localMustFlowStep(Node node1, Node node2) { none() }
216216

217217
/** Gets the type of `n` used for type pruning. */
218218
Type getNodeType(Node n) {
219-
suppressUnusedNode(n) and
219+
exists(n) and
220220
result instanceof VoidType // stub implementation
221221
}
222222

@@ -227,13 +227,10 @@ string ppReprType(Type t) { none() } // stub implementation
227227
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
228228
* a node of type `t1` to a node of type `t2`.
229229
*/
230-
pragma[inline]
231230
predicate compatibleTypes(Type t1, Type t2) {
232-
any() // stub implementation
231+
t1 instanceof VoidType and t2 instanceof VoidType // stub implementation
233232
}
234233

235-
private predicate suppressUnusedNode(Node n) { any() }
236-
237234
//////////////////////////////////////////////////////////////////////////////
238235
// Java QL library compatibility wrappers
239236
//////////////////////////////////////////////////////////////////////////////

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,7 @@ predicate localMustFlowStep(Node node1, Node node2) { none() }
988988

989989
/** Gets the type of `n` used for type pruning. */
990990
DataFlowType getNodeType(Node n) {
991-
suppressUnusedNode(n) and
991+
exists(n) and
992992
result instanceof VoidType // stub implementation
993993
}
994994

@@ -999,13 +999,10 @@ string ppReprType(DataFlowType t) { none() } // stub implementation
999999
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
10001000
* a node of type `t1` to a node of type `t2`.
10011001
*/
1002-
pragma[inline]
10031002
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
1004-
any() // stub implementation
1003+
t1 instanceof VoidType and t2 instanceof VoidType // stub implementation
10051004
}
10061005

1007-
private predicate suppressUnusedNode(Node n) { any() }
1008-
10091006
//////////////////////////////////////////////////////////////////////////////
10101007
// Java QL library compatibility wrappers
10111008
//////////////////////////////////////////////////////////////////////////////

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,7 +2483,7 @@ private predicate uselessTypebound(DataFlowType dt) {
24832483
)
24842484
}
24852485

2486-
pragma[inline]
2486+
pragma[nomagic]
24872487
private predicate compatibleTypesDelegateLeft(DataFlowType dt1, DataFlowType dt2) {
24882488
exists(Gvn::GvnType t1, Gvn::GvnType t2 |
24892489
t1 = exprNode(dt1.getADelegateCreation()).(NodeImpl).getDataFlowType().asGvnType() and
@@ -2507,7 +2507,7 @@ private predicate compatibleTypesDelegateLeft(DataFlowType dt1, DataFlowType dt2
25072507
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
25082508
* a node of type `t1` to a node of type `t2`.
25092509
*/
2510-
pragma[inline]
2510+
pragma[nomagic]
25112511
predicate compatibleTypes(DataFlowType dt1, DataFlowType dt2) {
25122512
exists(Gvn::GvnType t1, Gvn::GvnType t2 |
25132513
t1 = dt1.asGvnType() and

go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,8 @@ string ppReprType(DataFlowType t) { none() }
222222
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
223223
* a node of type `t1` to a node of type `t2`.
224224
*/
225-
pragma[inline]
226225
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
227-
any() // stub implementation
226+
t1 = TTodoDataFlowType() and t2 = TTodoDataFlowType() // stub implementation
228227
}
229228

230229
//////////////////////////////////////////////////////////////////////////////

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -371,18 +371,12 @@ string ppReprType(DataFlowType t) {
371371
else result = t.toString()
372372
}
373373

374-
pragma[nomagic]
375-
private predicate compatibleTypes0(DataFlowType t1, DataFlowType t2) {
376-
erasedHaveIntersection(t1, t2)
377-
}
378-
379374
/**
380375
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
381376
* a node of type `t1` to a node of type `t2`.
382377
*/
383-
bindingset[t1, t2]
384-
pragma[inline_late]
385-
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { compatibleTypes0(t1, t2) }
378+
pragma[nomagic]
379+
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { erasedHaveIntersection(t1, t2) }
386380

387381
/** A node that performs a type cast. */
388382
class CastNode extends ExprNode {

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ predicate neverSkipInPathGraph(Node n) {
564564
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
565565
* a node of type `t1` to a node of type `t2`.
566566
*/
567-
pragma[inline]
568567
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() }
569568

570569
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
@@ -576,8 +575,7 @@ predicate localMustFlowStep(Node nodeFrom, Node nodeTo) { none() }
576575
*/
577576
DataFlowType getNodeType(Node node) {
578577
result = TAnyFlow() and
579-
// Suppress unused variable warning
580-
node = node
578+
exists(node)
581579
}
582580

583581
/** Gets a string representation of a type returned by `getErasedRepr`. */

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2087,7 +2087,6 @@ private predicate compatibleTypesNonSymRefl(DataFlowType t1, DataFlowType t2) {
20872087
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
20882088
* a node of type `t1` to a node of type `t2`.
20892089
*/
2090-
pragma[inline]
20912090
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
20922091
t1 = t2
20932092
or

shared/dataflow/codeql/dataflow/DataFlow.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ signature module InputSig<LocationSig Location> {
142142
* steps, then it will check that the types of `n1` and `n2` are compatible.
143143
* If they are not, then flow will be blocked.
144144
*/
145-
bindingset[t1, t2]
146145
predicate compatibleTypes(DataFlowType t1, DataFlowType t2);
147146

148147
/**

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,7 +2928,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29282928
// the cons candidates including types are used to construct subsequent
29292929
// access path approximations.
29302930
t0 = t and
2931-
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and
2931+
(if castingNodeEx(node) then compatibleTypesFilter(node.getDataFlowType(), t0) else any()) and
29322932
(
29332933
notExpectsContent(node)
29342934
or
@@ -2940,7 +2940,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29402940
predicate typecheckStore(Typ typ, DataFlowType contentType) {
29412941
// We need to typecheck stores here, since reverse flow through a getter
29422942
// might have a different type here compared to inside the getter.
2943-
compatibleTypes(typ, contentType)
2943+
compatibleTypesFilter(typ, contentType)
29442944
}
29452945
}
29462946

@@ -2951,7 +2951,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29512951
if castingNodeEx(node)
29522952
then
29532953
exists(DataFlowType nt | nt = node.getDataFlowType() |
2954-
if typeStrongerThanFilter(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0)
2954+
if typeStrongerThanFilter(nt, t0)
2955+
then t = nt
2956+
else (
2957+
compatibleTypesFilter(nt, t0) and t = t0
2958+
)
29552959
)
29562960
else t = t0
29572961
}
@@ -3050,7 +3054,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
30503054
predicate typecheckStore(Typ typ, DataFlowType contentType) {
30513055
// We need to typecheck stores here, since reverse flow through a getter
30523056
// might have a different type here compared to inside the getter.
3053-
compatibleTypes(typ, contentType)
3057+
compatibleTypesFilter(typ, contentType)
30543058
}
30553059
}
30563060

@@ -3306,7 +3310,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
33063310

33073311
bindingset[typ, contentType]
33083312
predicate typecheckStore(Typ typ, DataFlowType contentType) {
3309-
compatibleTypes(typ, contentType)
3313+
compatibleTypesFilter(typ, contentType)
33103314
}
33113315
}
33123316

@@ -4246,7 +4250,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
42464250
Stage5::storeStepCand(mid.getNodeExOutgoing(), _, c, node, contentType, t) and
42474251
state = mid.getState() and
42484252
cc = mid.getCallContext() and
4249-
compatibleTypes(t0, contentType)
4253+
compatibleTypesFilter(t0, contentType)
42504254
)
42514255
}
42524256

@@ -5296,7 +5300,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
52965300
storeExUnrestricted(midNode, c, node, contentType, t2) and
52975301
ap2.getHead() = c and
52985302
ap2.len() = unbindInt(ap1.len() + 1) and
5299-
compatibleTypes(t1, contentType)
5303+
compatibleTypesFilter(t1, contentType)
53005304
)
53015305
}
53025306

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
288288
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
289289
not expectsContent(node, _) and
290290
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
291-
then compatibleTypes(t, getNodeDataFlowType(node))
291+
then compatibleTypesFilter(t, getNodeDataFlowType(node))
292292
else any()
293293
}
294294

@@ -886,6 +886,9 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
886886
cached
887887
predicate nodeDataFlowType(Node n, DataFlowType t) { t = getNodeType(n) }
888888

889+
cached
890+
predicate compatibleTypesCached(DataFlowType t1, DataFlowType t2) { compatibleTypes(t1, t2) }
891+
889892
cached
890893
predicate typeStrongerThanCached(DataFlowType t1, DataFlowType t2) { typeStrongerThan(t1, t2) }
891894

@@ -1121,7 +1124,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
11211124
exists(ParameterPosition ppos |
11221125
viableParam(call, ppos, p) and
11231126
argumentPositionMatch(call, arg, ppos) and
1124-
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and
1127+
compatibleTypesFilter(getNodeDataFlowType(arg), getNodeDataFlowType(p)) and
11251128
golangSpecificParamArgFilter(call, p, arg)
11261129
)
11271130
}
@@ -1274,10 +1277,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
12741277
then
12751278
// normal flow through
12761279
read = TReadStepTypesNone() and
1277-
compatibleTypes(getNodeDataFlowType(p), getNodeDataFlowType(node))
1280+
compatibleTypesFilter(getNodeDataFlowType(p), getNodeDataFlowType(node))
12781281
or
12791282
// getter
1280-
compatibleTypes(read.getContentType(), getNodeDataFlowType(node))
1283+
compatibleTypesFilter(read.getContentType(), getNodeDataFlowType(node))
12811284
else any()
12821285
}
12831286

@@ -1310,7 +1313,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
13101313
readStepWithTypes(mid, read.getContainerType(), read.getContent(), node,
13111314
read.getContentType()) and
13121315
Cand::parameterValueFlowReturnCand(p, _, true) and
1313-
compatibleTypes(getNodeDataFlowType(p), read.getContainerType())
1316+
compatibleTypesFilter(getNodeDataFlowType(p), read.getContainerType())
13141317
)
13151318
or
13161319
parameterValueFlow0_0(TReadStepTypesNone(), p, node, read, model)
@@ -1371,11 +1374,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
13711374
|
13721375
// normal flow through
13731376
read = TReadStepTypesNone() and
1374-
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(out))
1377+
compatibleTypesFilter(getNodeDataFlowType(arg), getNodeDataFlowType(out))
13751378
or
13761379
// getter
1377-
compatibleTypes(getNodeDataFlowType(arg), read.getContainerType()) and
1378-
compatibleTypes(read.getContentType(), getNodeDataFlowType(out))
1380+
compatibleTypesFilter(getNodeDataFlowType(arg), read.getContainerType()) and
1381+
compatibleTypesFilter(read.getContentType(), getNodeDataFlowType(out))
13791382
)
13801383
}
13811384

@@ -1623,6 +1626,12 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
16231626
result = TMkCallEdge(call, tgt)
16241627
}
16251628

1629+
bindingset[t1, t2]
1630+
pragma[inline_late]
1631+
predicate compatibleTypesFilter(DataFlowType t1, DataFlowType t2) {
1632+
compatibleTypesCached(t1, t2)
1633+
}
1634+
16261635
bindingset[t1, t2]
16271636
pragma[inline_late]
16281637
predicate typeStrongerThanFilter(DataFlowType t1, DataFlowType t2) {
@@ -1833,7 +1842,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
18331842
if typeStrongerThanCached(t2, t1)
18341843
then result = t2
18351844
else (
1836-
compatibleTypes(t1, t2) and result = t1
1845+
compatibleTypesFilter(t1, t2) and result = t1
18371846
)
18381847
}
18391848

@@ -1955,7 +1964,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
19551964
exists(DataFlowType t1, DataFlowType t2 |
19561965
typeFlowArgType(arg, t1, cc) and
19571966
relevantArgParamIn(arg, p, t2) and
1958-
compatibleTypes(t1, t2)
1967+
compatibleTypesFilter(t1, t2)
19591968
)
19601969
}
19611970

@@ -1999,7 +2008,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
19992008
exists(DataFlowType t1, DataFlowType t2 |
20002009
typeFlowParamType(p, t1, false) and
20012010
relevantArgParamOut(arg, p, t2) and
2002-
compatibleTypes(t1, t2)
2011+
compatibleTypesFilter(t1, t2)
20032012
)
20042013
}
20052014

0 commit comments

Comments
 (0)