-
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
False positive with field nullability stored in local variable #98
Comments
Yeah, NullAway does not track local variable aliases so it misses this case. Like #35 I think we could support this eventually by doing a more precise analysis in cases where we are going to report an error. Going to mark this as low priority for now but it would be a good project to take on eventually |
BTW thanks for all the reports @ben-manes! Please keep them coming 😄 |
Unfortunately I think that I have to give up on the target project since it is non-idiomatic for performance reasons. It uses a lot of nullable fields that are enabled in certain configurations, as indicated by code generated subclasses. Since those usage paths can only occur when non-null, and NullAway cannot track deeply enough, many false positives are hard to easily resolve without turning the whole thing off. But it was a nice experiment to try this out! |
Ok no problem! One thing is if you control the code generator, you can tweak it to generate downcasts or other warning suppressions so you can still use NullAway on other more idiomatic parts of the code base. (The downcasts may not be tolerable if the code is super performance critical.) We'll keep working on improving NullAway in the meantime. |
Yes, though the codegen is only for minimizing fields and the logic is in the base class. I would expect inlining to remove the downcasts, so it would be free. But the project has exceeded its complexity budget and this would add obscurity when already challenging. But this is a good trick to know if I decide to introduce NullAway to a work project. Thanks! |
Making progress using your trick, so we'll see how it comes out :) Another case where this issue occurs in the pattern,
This scenario is about readability of the code by naming the condition when used multiple times in a method. Using the explicit check each time would be okay, but convey less when maintaining and need reparsing of what null means. But due to not tracking the invocation on |
Awesome! :) Regarding your |
In this case it was only once, but that is because I usually extract those out to query methods. Since method tracking isn't supported, that has been a largest case of false positives. My present goal is to have it pass in order to review the benefits. There are a lot more suppressions than I'd like since inference is too locally scoped. But I also think it may have found one or two possible errors in a JSR adapter, so it will be worthwhile regardless. Since this requires more extensive annotations just like the Checker Framework does, I'm curious to run their analysis afterwards to see how it compares. |
Everything works nicely! I had forgotten why the CheckerFramework is painful, so this is a nice compromise. :) |
Great, so glad you got things working! And thanks again for all the reports. We'll dig through them more in the new year. Regarding the query methods, I think we can actually support those more easily with a new annotation, rather than requiring a library model. I'll re-open another issue specifically around that one. |
Joy, integrated into my project. There are 50 targeted suppressions and neutral impact to code readability. Thanks for all of the hard work :) |
Awesome! Thanks for all your reports and feedback! |
@msridhar, what are the chances of this being picked up? We at Canva are rolling out NullAway in our code base, and there's been pushback from some engineers finding it cumbersome to work around NullAway's limitation. Here's an example that's similar to the String potentiallyNull = // ...
boolean definitelyNotNull = potentiallyNull != null;
if (definitelyNotNull) {
int length = potentiallyNull.length(); // <-- NullAway warning
}
if (potentiallyNull != null) {
int length = potentiallyNull.length(); // <-- No warning
} We'd also be happy to contribute if that's the quickest way forward, just let me know how to help. |
@wbadam exciting to hear you are working on rolling out NullAway at Canva! Given the number of times this has come up, I would be open to trying to address cases like your example. Unfortunately it may not be a super-quick thing to implement. An over-simplified view is that right now, NullAway keeps track of a set of variables that are Do you or one of your teammates feel willing / able to dig into this a bit? Having more help would definitely make the exploration go faster. I am slammed for at least the next couple of days and won't have time to look more closely. But I can try to give pointers to the relevant code. |
@msridhar certainly happy to look into it, a direction to the relevant code would be much appreciated! |
I have renamed this issue to focus on the false positives stemming from cases like those in #98 (comment).
Thanks, @wbadam, I appreciate it. I still need to do some thinking and exploration as to the best way to support this. Right now, the state tracked by NullAway during local dataflow analysis is a I have some other deadlines and an upcoming holiday, so I won't be able to dig into this more until after mid-April. If anyone has cycles and wants to attempt some prototyping based on the above, feel free. Otherwise, I will take a look when I have some time available. |
Our C++ colleagues at Google have done some work to handle variables like the |
Thanks a lot @cpovirk! That's very interesting. The inlining approach is appealing in terms of trying to make the results of dataflow not depend on whether you store certain types of conditions in an (effectively final?) local variable or check them directly. I'm still unsure of the best way to proceed for NullAway. I hope to be able to put in more time on this soon. |
Hitting this a reasonable amount as well for Chrome code. Same examples as above. E.g.:
|
I've been meaning to look more at this for a while, just haven't had the cycles. I'll see if I can prioritize it. Thank you @agrieve for the additional example. |
In this case, a
@Nullable
field is stored to a local variable. When the field is used in a null condition an error occurs, but if the variable is used then it does not. It seems the data flow analysis does not realize they are the same.The text was updated successfully, but these errors were encountered: