Skip to content

Commit c2b9974

Browse files
authored
Merge pull request #9951 from aschackmull/java/notintersect-perf
Java: Improve join-order for `not haveIntersection`.
2 parents 96091e4 + aabdf84 commit c2b9974

File tree

4 files changed

+26
-7
lines changed

4 files changed

+26
-7
lines changed

java/ql/lib/semmle/code/java/Type.qll

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,8 +1194,8 @@ private Type erase(Type t) {
11941194
}
11951195

11961196
/**
1197-
* Is there a common (reflexive, transitive) subtype of the erasures of
1198-
* types `t1` and `t2`?
1197+
* Holds if there is a common (reflexive, transitive) subtype of the erasures of
1198+
* types `t1` and `t2`.
11991199
*
12001200
* If there is no such common subtype, then the two types are disjoint.
12011201
* However, the converse is not true; for example, the parameterized types
@@ -1212,6 +1212,25 @@ predicate haveIntersection(RefType t1, RefType t2) {
12121212
)
12131213
}
12141214

1215+
/**
1216+
* Holds if there is no common (reflexive, transitive) subtype of the erasures
1217+
* of types `t1` and `t2`.
1218+
*
1219+
* If there is no such common subtype, then the two types are disjoint.
1220+
* However, the converse is not true; for example, the parameterized types
1221+
* `List<Integer>` and `Collection<String>` are disjoint,
1222+
* but their erasures (`List` and `Collection`, respectively)
1223+
* do have common subtypes (such as `List` itself).
1224+
*
1225+
* For the definition of the notion of *erasure* see JLS v8, section 4.6 (Type Erasure).
1226+
*/
1227+
bindingset[t1, t2]
1228+
predicate notHaveIntersection(RefType t1, RefType t2) {
1229+
exists(RefType e1, RefType e2 | e1 = erase(t1) and e2 = erase(t2) |
1230+
not erasedHaveIntersection(e1, e2)
1231+
)
1232+
}
1233+
12151234
/**
12161235
* Holds if there is a common (reflexive, transitive) subtype of the erased
12171236
* types `t1` and `t2`.

java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class MismatchedContainerAccess extends MethodAccess {
118118
containerAccess(package, type, p, this.getCallee().getSignature(), i)
119119
|
120120
t = this.getCallee().getDeclaringType() and
121-
t.getAnAncestor().getSourceDeclaration() = g and
121+
t.getASourceSupertype*().getSourceDeclaration() = g and
122122
g.hasQualifiedName(package, type) and
123123
indirectlyInstantiates(t, g, p, result)
124124
)
@@ -139,7 +139,7 @@ from MismatchedContainerAccess ma, RefType typearg, RefType argtype, int idx
139139
where
140140
typearg = ma.getReceiverElementType(idx).getSourceDeclaration() and
141141
argtype = ma.getArgumentType(idx) and
142-
not haveIntersection(typearg, argtype)
142+
notHaveIntersection(typearg, argtype)
143143
select ma.getArgument(idx),
144144
"Actual argument type '" + argtype.getName() + "'" +
145145
" is incompatible with expected argument type '" + typearg.getName() + "'."

java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class MismatchedContainerModification extends MethodAccess {
8888
containerModification(package, type, p, this.getCallee().getSignature(), i)
8989
|
9090
t = this.getCallee().getDeclaringType() and
91-
t.getAnAncestor().getSourceDeclaration() = g and
91+
t.getASourceSupertype*().getSourceDeclaration() = g and
9292
g.hasQualifiedName(package, type) and
9393
indirectlyInstantiates(t, g, p, result)
9494
)
@@ -109,7 +109,7 @@ from MismatchedContainerModification ma, RefType elementtype, RefType argtype, i
109109
where
110110
elementtype = ma.getReceiverElementType(idx).getSourceDeclaration() and
111111
argtype = ma.getArgumentType(idx) and
112-
not haveIntersection(elementtype, argtype)
112+
notHaveIntersection(elementtype, argtype)
113113
select ma.getArgument(idx),
114114
"Actual argument type '" + argtype.getName() + "'" +
115115
" is incompatible with expected argument type '" + elementtype.getName() + "'."

java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ where
5757
else recvtp = ma.getMethod().getDeclaringType()
5858
) and
5959
argtp = ma.getArgumentType() and
60-
not haveIntersection(recvtp, argtp)
60+
notHaveIntersection(recvtp, argtp)
6161
select ma,
6262
"Call to equals() comparing incomparable types " + recvtp.getName() + " and " + argtp.getName() +
6363
"."

0 commit comments

Comments
 (0)