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 摘要。