Skip to content
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

JSpecify: Reason about nullability of reads from arrays #875

Merged
merged 13 commits into from
Feb 6, 2024

Conversation

armughan11
Copy link
Collaborator

@armughan11 armughan11 commented Dec 6, 2023

This is a continuation of #850 where the behavior of @Nullable annotations on the array was modified.
With this PR, the aim is to allow @Nullable annotations on array contents in JSpecify mode, and to process these annotations when handling reads from arrays. This PR does not handle checking writes to array elements, nor does it support reasoning about null checks on array elements in local type refinement.

Copy link

codecov bot commented Dec 6, 2023

Codecov Report

Attention: 5 lines in your changes are missing coverage. Please review.

Comparison is base (3fc9b8a) 86.98% compared to head (87d3cc6) 86.96%.
Report is 1 commits behind head on master.

Files Patch % Lines
...c/main/java/com/uber/nullaway/NullabilityUtil.java 62.50% 1 Missing and 2 partials ⚠️
...away/src/main/java/com/uber/nullaway/NullAway.java 87.50% 0 Missing and 1 partial ⚠️
...llaway/dataflow/AccessPathNullnessPropagation.java 85.71% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #875      +/-   ##
============================================
- Coverage     86.98%   86.96%   -0.02%     
- Complexity     1959     1967       +8     
============================================
  Files            77       77              
  Lines          6330     6352      +22     
  Branches       1223     1231       +8     
============================================
+ Hits           5506     5524      +18     
- Misses          420      421       +1     
- Partials        404      407       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Collaborator

@msridhar msridhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great start. I've added a couple comments for next steps

Comment on lines 2289 to 2298
ArrayAccessTree arrayAccess = (ArrayAccessTree) expr;
ExpressionTree arrayExpr = arrayAccess.getExpression();
Symbol arraySymbol = ASTHelpers.getSymbol(arrayExpr);
if (arraySymbol != null) {
for (Attribute.TypeCompound t : arraySymbol.getRawTypeAttributes()) {
for (TypeAnnotationPosition.TypePathEntry entry : t.position.location) {
if (entry.tag == TypeAnnotationPosition.TypePathEntryKind.ARRAY) {
return true;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good start! I think we want to extend this logic, as follows. Move the ARRAY_ACCESS case down under this switch:

The logic should be just to set exprMayBeNull to true iff the type of the array contents is @Nullable (similar to the logic you have already written).

Then, we need to update the dataflow logic as well; that logic is here:

https://github.com/uber/NullAway/blob/master/nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java#L794-L794

For now, rather than just using defaultAssumption we can again set the nullability of the expression based on the type of the array contents. So, the logic you wrote already should be extracted to a utility method that can be called from both places. Eventually, we want to extend the dataflow logic to handle null checks, so code like if (fizz[0] != null) { fizz[0].length(); } does not issue any warnings. But that doesn't need to happen in this PR.

" static void foo() {",
" if (fizz != null) {",
" String s = fizz[0];",
" // TODO: This should report due to dereference of @Nullable s",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failure here has nothing to do with annotations being in both places. It's because we haven't updated our dataflow support yet.

@armughan11 armughan11 marked this pull request as ready for review February 5, 2024 10:58
Copy link
Collaborator

@msridhar msridhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One key comment and needs some cleanup, but overall looks good!

if (arraySymbol != null) {
for (Attribute.TypeCompound t : arraySymbol.getRawTypeAttributes()) {
for (TypeAnnotationPosition.TypePathEntry entry : t.position.location) {
if (entry.tag == TypeAnnotationPosition.TypePathEntryKind.ARRAY) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to check whether the annotation is actually @Nullable. This just checks for the presence of some annotation. And yes this logic should be extracted to a utility method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed!

boolean isElementNullable = false;
for (Attribute.TypeCompound t : arraySymbol.getRawTypeAttributes()) {
for (TypeAnnotationPosition.TypePathEntry entry : t.position.location) {
if (entry.tag == TypeAnnotationPosition.TypePathEntryKind.ARRAY) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above, check for @Nullable

Copy link
Collaborator

@msridhar msridhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I will land this shortly

@msridhar msridhar changed the title JSpecify: Add Array Contents Nullability Annotations JSpecify: Reason about nullability of reads from arrays Feb 6, 2024
@msridhar msridhar enabled auto-merge (squash) February 6, 2024 04:03
@msridhar msridhar merged commit 5068956 into uber:master Feb 6, 2024
10 of 12 checks passed
@armughan11 armughan11 deleted the jspecify-array-contents-nullability branch June 3, 2024 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants