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);