From b8a03464bf865c964a8607ccb543d4e70f0fd027 Mon Sep 17 00:00:00 2001 From: Henning Makholm Date: Thu, 7 Feb 2019 21:12:17 +0100 Subject: [PATCH] Fix false positives in java/unused parameter Methods that are mentioned in a member reference expression should count as rootdefs for the unused parameter query. Such methods have to match the functional interface of the reference expression, so it is to be expected that they will sometimes have to declare parameters that they don't actually use. --- java/ql/src/semmle/code/java/deadcode/DeadCode.qll | 4 ++++ .../query-tests/dead-code/UselessParameter/Test.java | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/java/ql/src/semmle/code/java/deadcode/DeadCode.qll b/java/ql/src/semmle/code/java/deadcode/DeadCode.qll index 80106865799..2790f3f794c 100644 --- a/java/ql/src/semmle/code/java/deadcode/DeadCode.qll +++ b/java/ql/src/semmle/code/java/deadcode/DeadCode.qll @@ -292,6 +292,10 @@ class RootdefCallable extends Callable { // a body that also doesn't. not hasUsefulBody(this) and not exists(Method m | hasUsefulBody(m) | m.overridesOrInstantiates+(this)) + or + // Methods that are the target of a member reference need to implement + // the exact signature of the resulting functional interface. + exists(MemberRefExpr mre | mre.getReferencedCallable() = this) } } diff --git a/java/ql/test/query-tests/dead-code/UselessParameter/Test.java b/java/ql/test/query-tests/dead-code/UselessParameter/Test.java index 645f7290855..57554544e4c 100644 --- a/java/ql/test/query-tests/dead-code/UselessParameter/Test.java +++ b/java/ql/test/query-tests/dead-code/UselessParameter/Test.java @@ -40,6 +40,10 @@ abstract class C implements I { } } +interface F { + void doSomething(int arg2); +} + public class Test { // OK: external interface public static void main(String[] args) {} @@ -54,6 +58,13 @@ public class Test { public static void foo(Object bar) { throw new UnsupportedOperationException(); } + + public static F getF() { + return Test::myFImplementation; + } + + // OK: mentioned in member reference + private static void myFImplementation(int foo) {} // OK: native method native int baz(int x);