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:
Description of the issue
Currently QL always pretends that the parent of a
LambdaExpr.getExprBody()is aReturnStmt, however that is incorrect.If the lambda implements an interface method with
voidas return type, the parent must not beReturnStmt, but should beExprStmtinstead.Example query:
The current behavior likely causes false negatives for multiple queries in this repository because they check
expr.getParent() instanceof ExprStmtto 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(): Stringfor aRunnable r = this::toString();.So there are three bugs:
LambdaExpr.asMethod()hasReturnStmtinstead ofExprStmtfor target interface methods withvoidas return typeMemberRefExpr.asMethod()hasReturnStmtinstead ofExprStmtfor target interface methods withvoidas return typeMemberRefExpr.asMethod()has wrongMethod.getReturnType()(i.e. non-void) for target interface methods withvoidas return type