Skip to content

Commit 22ebe68

Browse files
authored
Merge pull request #7132 from aschackmull/java/overrides
Java: Fix overrides to not be transitive.
2 parents 1645fcf + 69671ce commit 22ebe68

File tree

9 files changed

+23
-11
lines changed

9 files changed

+23
-11
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* The predicate `Method.overrides(Method)` was accidentally transitive. This has been fixed. This fix also affects `Method.overridesOrInstantiates(Method)` and `Method.getASourceOverriddenMethod()`.

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,20 @@ private predicate overrides(Method m1, Method m2) {
285285
or
286286
m2.isProtected()
287287
or
288-
m2.isPackageProtected() and t1.getPackage() = t2.getPackage()
288+
m2.isPackageProtected() and
289+
pragma[only_bind_out](t1.getPackage()) = pragma[only_bind_out](t2.getPackage())
290+
)
291+
}
292+
293+
pragma[nomagic]
294+
private predicate overridesCandidateType(RefType tsup, string sig, RefType t, Method m) {
295+
virtualMethodWithSignature(sig, t, m) and
296+
t.extendsOrImplements(tsup)
297+
or
298+
exists(RefType mid |
299+
overridesCandidateType(mid, sig, t, m) and
300+
mid.extendsOrImplements(tsup) and
301+
not virtualMethodWithSignature(sig, mid, _)
289302
)
290303
}
291304

@@ -294,11 +307,10 @@ private predicate overrides(Method m1, Method m2) {
294307
* ignoring any access modifiers. Additionally, this predicate binds
295308
* `t1` to the type declaring `m1` and `t2` to the type declaring `m2`.
296309
*/
297-
pragma[noopt]
310+
cached
298311
predicate overridesIgnoringAccess(Method m1, RefType t1, Method m2, RefType t2) {
299312
exists(string sig |
300-
virtualMethodWithSignature(sig, t1, m1) and
301-
t1.extendsOrImplements+(t2) and
313+
overridesCandidateType(t2, sig, t1, m1) and
302314
virtualMethodWithSignature(sig, t2, m2)
303315
)
304316
}

java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class ManagedBeanImplEntryPoint extends EntryPoint, RegisteredManagedBeanImpl {
262262
// Find the method that will be called for each method on each managed bean that this class
263263
// implements.
264264
this.inherits(result) and
265-
result.overrides(this.getAnImplementedManagedBean().getAMethod())
265+
result.overrides+(this.getAnImplementedManagedBean().getAMethod())
266266
}
267267
}
268268

java/ql/lib/semmle/code/java/deadcode/StrutsEntryPoints.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class Struts1ActionEntryPoint extends EntryPoint, Class {
1919
exists(Method methodFromAction |
2020
methodFromAction.getDeclaringType().hasQualifiedName("org.apache.struts.action", "Action")
2121
|
22-
result.(Method).overrides(methodFromAction)
22+
result.(Method).overrides+(methodFromAction)
2323
)
2424
or
2525
this.getASupertype*().hasQualifiedName("org.apache.struts.actions", "DispatchAction") and

java/ql/lib/semmle/code/java/frameworks/Thrift.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class ThriftIface extends Interface {
2727

2828
Method getAnImplementingMethod() {
2929
result.getDeclaringType().(Class).getASupertype+() = this and
30-
result.overrides(this.getAMethod()) and
30+
result.overrides+(this.getAMethod()) and
3131
not result.getFile() = this.getFile()
3232
}
3333
}

java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJB.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ class RemoteInterface extends Interface {
572572
* abstract methods or overriding within an interface hierarchy.
573573
*/
574574
Method getARemoteMethodImplementationChecked() {
575-
result.overrides(this.getARemoteMethod()) and
575+
result.overrides+(this.getARemoteMethod()) and
576576
exists(result.getBody())
577577
}
578578

java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ where
5454
sup.isSynchronized() and
5555
not sub.isSynchronized() and
5656
not delegatingOverride(sub, sup) and
57-
not exists(Method mid | sub.overrides(mid) and mid.overrides(sup)) and
5857
supSrc = sup.getDeclaringType().getSourceDeclaration()
5958
select sub,
6059
"Method '" + sub.getName() + "' overrides a synchronized method in $@ but is not synchronized.",

java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ where
4545
// which is an access to the object being initialized, ...
4646
ma = unqualifiedCallToNonAbstractMethod(c, m) and
4747
// ... there exists an overriding method in a subtype,
48-
n.overrides(m) and
48+
n.overrides+(m) and
4949
n.getDeclaringType().getASupertype+() = c.getDeclaringType() and
5050
// ... the method is in a supertype of c,
5151
m.getDeclaringType() = c.getDeclaringType().getASupertype*() and

java/ql/test/library-tests/overrides/ConstructedOverrides2.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@
33
| ConstructedOverrides.java:17:7:17:9 | Sub | usedGeneric(U, String) | Super.class:0:0:0:0 | Super<String> | usedGeneric(U, String) |
44
| ConstructedOverrides.java:23:7:23:10 | Sub2 | unusedGeneric(V, String) | Super.class:0:0:0:0 | Super<String> | unusedGeneric(U, String) |
55
| ConstructedOverrides.java:23:7:23:10 | Sub2 | usedGeneric(V, String) | ConstructedOverrides.java:17:7:17:9 | Sub | usedGeneric(U, String) |
6-
| ConstructedOverrides.java:23:7:23:10 | Sub2 | usedGeneric(V, String) | Super.class:0:0:0:0 | Super<String> | usedGeneric(U, String) |

0 commit comments

Comments
 (0)