Skip to content

Java: LambdaExpr.getExprBody() parent is always ReturnStmt #3605

Open
@Marcono1234

Description

@Marcono1234

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() has ReturnStmt instead of ExprStmt for target interface methods with void as return type
  • MemberRefExpr.asMethod() has ReturnStmt instead of ExprStmt for target interface methods with void as return type
  • MemberRefExpr.asMethod() has wrong Method.getReturnType() (i.e. non-void) for target interface methods with void as return type

Metadata

Metadata

Assignees

No one assigned

    Labels

    JavaquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions