github / github/codeql

Java: LambdaExpr.getExprBody() parent is always ReturnStmt

Open
#3,605 3 comments 0 reactions 0 assignees View on GitHub
Java question
Dominant language
CodeQL
Stars
10.1k
Forks
2.1k
Avg merge
2d 15h
Merged PRs (30d)
141

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:
```ql
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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.