-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible bug in Optional.empty() check with exception handling #557
Comments
Hi @noobgramming, for this line: if (optCommand.isEmpty()) { Should that be |
Hey @msridhar, waiting for confirmation from @noobgramming , but I think the if-check is indeed on an unrelated variable, and the logic for why
In that case, I do see a discrepancy between our handling of See the following test cases:
No idea what causes the difference. |
@lazaroclapp that's really interesting. I have no idea why there is an error reported for the |
Yes sorry. This was extracted from much larger, more confusing code :) I tried to simplify Updated version below still triggers the behavior. I extracted the code again, verifying it works this time public void nullCheck(Configuration configuration) {
Optional<Object> optObject;
try {
optObject = doThingThatMightThrow(); // always returns Optional.empty()
} catch (Exception e) {
if (configuration.debugMode()) {
throw e;
} else {
log.error(
"error",
e);
return;
}
}
if (optObject.isEmpty()) {
log.info("info ");
return;
} else {
final var obj = optObject.get(); // <-- linter warning here [NullAway] Invoking get() on possibly empty Optional optObject
}
} However, @lazaroclapp your simplification may still be correct because I'm unsure which part (the exception handling or empty check) is causing NullAway to act weird. I included the exception handling because I found it unlikely that such a straightforward empty check was causing this EDIT: Also, this is on Java 17 in case that matters |
Thanks, @noobgramming. This definitely looks like a bug. We will look as soon as we get some time |
I finally got some time to dig a bit into this. I found that the same kind of false positive occurs with this test: @Test
public void returnFromCatch() {
defaultCompilationHelper
.addSourceLines(
"Test.java",
"package com.uber;",
"import javax.annotation.Nullable;",
"class Test {",
" @Nullable Object f;",
" String foo() {",
" Test t = new Test();",
" try {",
" t.f = new Object();",
" } catch (Exception e) {",
" return \"error\";",
" }",
// false positive warning for this line
" return t.f.toString();",
" }",
"}")
.doTest();
} The issue turns out to have nothing to do with exceptions. The issue is that we will not track an access path for a field if the root is not NullAway/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java Lines 531 to 540 in f3c1ebf
I presume we did this for performance reasons way back when (this code has not changed since the initial open-source commit of NullAway). This impacts handling of the optional case as well, since we simulate the contents of an The downside of this optimization is confusing tool behavior, like in the case originally reported here. I'd be open to trying to track more access paths as part of analysis, as long as we measure the performance impact, both on our micro-benchmarks and also on internal code at Uber. E.g., we could track an access path after an assignment to a field of any local variable, not just @lazaroclapp any thoughts here? I may hold off on this change until after the next release, since at that point we expect to add NullAway itself as another performance benchmark. |
🤦♂️ Ignore my previous comment. I figured out something much simpler is going on here; we don't have any support for the |
Fixes #557. The changes includes some other cleanup in `OptionalEmptinessHandler`.
Hello! I'm trying out
CheckOptionalEmptiness
and I think I found a bug.It reports Optional after exception handling as possibly empty, even if all code paths in try{} throw or return. And it does so even when you pre-initialize to Optional.empty()
This code example isn't right, see updated one a few comments below
The text was updated successfully, but these errors were encountered: