Open
Description
Description of the issue
Currently QL always pretends that the parent of a LambdaExpr.getExprBody()
is a ReturnStmt
, however that is incorrect.
If the lambda implements an interface method with void
as return type, the parent must not be ReturnStmt
, but should be ExprStmt
instead.
Example query:
import java
class RunMethod extends Method {
RunMethod() {
getDeclaringType().hasQualifiedName("java.lang", "Runnable")
and hasStringSignature("run()")
}
}
from LambdaExpr lambda, Expr expr
where
expr = lambda.getExprBody()
and expr.getParent() instanceof ReturnStmt
and lambda.asMethod().getAnOverride*() instanceof RunMethod
select expr
The current behavior likely causes false negatives for multiple queries in this repository because they check expr.getParent() instanceof ExprStmt
to see if the return value of the call is discarded.
Edit: This apparently also affects the implicit method which MemberRefExpr.asMethod()
has as result. And there the implicit method also has the wrong return type, e.g. run(): String
for a Runnable r = this::toString();
.
So there are three bugs:
-
LambdaExpr.asMethod()
hasReturnStmt
instead ofExprStmt
for target interface methods withvoid
as return type -
MemberRefExpr.asMethod()
hasReturnStmt
instead ofExprStmt
for target interface methods withvoid
as return type -
MemberRefExpr.asMethod()
has wrongMethod.getReturnType()
(i.e. non-void
) for target interface methods withvoid
as return type