Skip to content

Commit 7dc5f94

Browse files
authored
Merge pull request github#2920 from aschackmull/java/typeflow-irrelevant-pruning
Java: Remove some irrelevant bounds from TypeFlow.
2 parents 0da554c + 0c30d7c commit 7dc5f94

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

java/ql/src/semmle/code/java/dataflow/TypeFlow.qll

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,13 +364,45 @@ private predicate typeFlow(TypeFlowNode n, RefType t) {
364364
typeFlowJoin(lastRank(n), n, t)
365365
}
366366

367+
pragma[nomagic]
368+
predicate erasedTypeBound(RefType t) {
369+
exists(RefType t0 | typeFlow(_, t0) and t = t0.getErasure())
370+
}
371+
372+
pragma[nomagic]
373+
predicate typeBound(RefType t) { typeFlow(_, t) }
374+
375+
/**
376+
* Holds if we have a bound for `n` that is better than `t`, taking only erased
377+
* types into account.
378+
*/
379+
pragma[nomagic]
380+
private predicate irrelevantErasedBound(TypeFlowNode n, RefType t) {
381+
exists(RefType bound |
382+
typeFlow(n, bound)
383+
or
384+
n.getType() = bound and typeFlow(n, _)
385+
|
386+
t = bound.getErasure().(RefType).getASourceSupertype+() and
387+
erasedTypeBound(t)
388+
)
389+
}
390+
367391
/**
368392
* Holds if we have a bound for `n` that is better than `t`.
369393
*/
370-
pragma[noinline]
394+
pragma[nomagic]
371395
private predicate irrelevantBound(TypeFlowNode n, RefType t) {
372-
exists(RefType bound | typeFlow(n, bound) or n.getType() = bound |
373-
t = bound.getErasure().(RefType).getASourceSupertype+()
396+
exists(RefType bound |
397+
typeFlow(n, bound) and
398+
t = bound.getASupertype+() and
399+
typeBound(t) and
400+
typeFlow(n, t) and
401+
not t.getASupertype*() = bound
402+
or
403+
n.getType() = bound and
404+
typeFlow(n, t) and
405+
t = bound.getASupertype*()
374406
)
375407
}
376408

@@ -380,7 +412,8 @@ private predicate irrelevantBound(TypeFlowNode n, RefType t) {
380412
*/
381413
private predicate bestTypeFlow(TypeFlowNode n, RefType t) {
382414
typeFlow(n, t) and
383-
not irrelevantBound(n, t.getErasure())
415+
not irrelevantErasedBound(n, t.getErasure()) and
416+
not irrelevantBound(n, t)
384417
}
385418

386419
cached

java/ql/src/semmle/code/java/dispatch/ObjFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ private module Unification {
305305
arg2 = t2.getTypeArgument(pos)
306306
}
307307

308+
pragma[nomagic]
308309
predicate failsUnification(Type t1, Type t2) {
309310
unificationTargets(t1, t2) and
310311
(

java/ql/test/library-tests/typeflow/typeflow.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
| A.java:9:10:9:11 | f1 | ArrayList<Long> | true |
2-
| A.java:10:10:10:10 | l | List<Long> | false |
32
| A.java:11:19:11:20 | f2 | List<Long> | false |
43
| A.java:12:16:12:16 | x | List<Long> | false |
54
| A.java:14:9:14:9 | y | A | false |
6-
| A.java:18:11:18:12 | l2 | List<Integer> | false |
75
| A.java:19:9:19:9 | y | List<Integer> | false |
86
| A.java:26:14:26:14 | o | List<Long> | false |
97
| A.java:34:11:34:11 | x | Integer | false |

0 commit comments

Comments
 (0)