github / github/codeql

Java: LambdaExpr.getExprBody() parent is always ReturnStmt

未关闭
#3,605 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
Java question
主要语言
CodeQL
星标
10.1k
派生
2.1k
平均合并
2 天 15 小时
30 天内合并 PR
141

描述

**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

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。