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

Bogus null contract violation diagnostic at yield statements #3154

Merged
merged 2 commits into from
Oct 25, 2024

Conversation

srikanth-sankaran
Copy link
Contributor

@srikanth-sankaran srikanth-sankaran commented Oct 24, 2024

What it does

How to test

Author checklist

@srikanth-sankaran
Copy link
Contributor Author

@stephan-herrmann my first contribution to null analysis after 10 years hiatus. Be gentle and kind in review comments 😆

@srikanth-sankaran
Copy link
Contributor Author

but the provided value is null reads better as but the provided value may be null but that is nitpicking

@srikanth-sankaran srikanth-sankaran changed the title Pattern matching on sealed classes cannot infer NonNull (JDK 21) Bogus null contract violation diagnostic at yield statements Oct 24, 2024
@stephan-herrmann
Copy link
Contributor

but the provided value is null reads better as but the provided value may be null but that is nitpicking

Is that a linguistic hint? AFAICS there is no doubt about null at the two error locations in the new test, so 'is' is more precise than 'may be'. Do you disagree about this analysis?

Copy link
Contributor

@stephan-herrmann stephan-herrmann left a comment

Choose a reason for hiding this comment

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

Welcome back to null analysis, @srikanth-sankaran :)

You found the location that triggered incorrect behaviour. I hope you find my detailed comment helpful to further improve the change.

Comment on lines -58 to -59
if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled)
checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression);
Copy link
Contributor

Choose a reason for hiding this comment

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

So you successfully removed a bogus analysis for the price that NPE caused by yield will not be detected at all, right?

I admit that the current code is only useful in the narrow situation of return switch(v) { ... yield x; }

I believe the better course of action would be to identify the expected annotated type to which the yield value will be assigned, without taking the shortcut to the method return type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So you successfully removed a bogus analysis for the price that NPE caused by yield will not be detected at all, right?

I admit that the current code is only useful in the narrow situation of return switch(v) { ... yield x; }

Hold on, please take a look again!

I added a new test via a follow up commit that proves that a null injected by yield of a switch expression that is the directly returned will be detected: See org.eclipse.jdt.core.tests.compiler.regression.NullAnnotationTests21.testIssue2522_2()

Why would yield require special treatment under return anymore than ternary expression would ?

I believe the better course of action would be to identify the expected annotated type to which the yield value will be assigned, without taking the shortcut to the method return type.

This happens automatically! Just the same way this is complained against:

@NonNull Stuff l = switch (pm) {
					case Stuff s -> s;
					case null -> null; // error: Null type mismatch: required 'PatternMatching.@NonNull Stuff' but the provided value is null
					};

So do you have a snippet that shows a case where we would not detect a null injection due to the change here ?? I

Copy link
Contributor

Choose a reason for hiding this comment

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

Apologies, I forgot about how a switch expression collects result expressions and how various null-checking methods will drill into those result expressions, without the yield expression needing to do anything. The fact that I wrote my previous review comment on a train is only a weak excuse.

@srikanth-sankaran
Copy link
Contributor Author

but the provided value is null reads better as but the provided value may be null but that is nitpicking

Is that a linguistic hint? AFAICS there is no doubt about null at the two error locations in the new test, so 'is' is more precise than 'may be'. Do you disagree about this analysis?

No, please ignore that comment - I didn't realize we also have a variant but the provided value is inferred as @Nullable where the expression may be but also may not be null. So we are good.

Copy link
Contributor

@stephan-herrmann stephan-herrmann left a comment

Choose a reason for hiding this comment

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

Thanks, @srikanth-sankaran, for insisting. After more scrutiny I see no problem with this PR. Please go ahead.

@stephan-herrmann stephan-herrmann added the null Issues related to null pointer analysis label Oct 25, 2024
@srikanth-sankaran srikanth-sankaran merged commit 2e98dcb into eclipse-jdt:master Oct 25, 2024
10 checks passed
@srikanth-sankaran srikanth-sankaran deleted the Issue2522 branch October 25, 2024 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
null Issues related to null pointer analysis
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Switch Expression][Null] Bogus null contract violation diagnostic at yield statements
2 participants