Bug 494897 - [compiler][null][correlation] Wrong report about variable potentially being null
Summary: [compiler][null][correlation] Wrong report about variable potentially being null
Status: CLOSED DUPLICATE of bug 538421
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.6   Edit
Hardware: All All
: P4 enhancement (vote)
Target Milestone: 4.7 M1   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2016-05-30 06:06 EDT by Lukas Eder CLA
Modified: 2018-08-30 10:31 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lukas Eder CLA 2016-05-30 06:06:52 EDT
Consider the following code:

----------------------------------------------------------------------------
public class Test {
    void x() {
        Object o1 = null;
        Object o2 = null;

        E e = E.A;
        switch (e) {
            case A:
                o2 = "a";
                break;
            case B:
                o2 = "b";
                break;
            case C:
                o1 = "c";
                break;
            default:
                throw new RuntimeException();
        }

        if (o1 != null)
            o2 = o1;

        // Potential null pointer access: The variable o2 may be null at this location
        System.out.println(o2.toString());
    }

    enum E {
        A, B, C
    }
}
----------------------------------------------------------------------------

The o2.toString() call is safe in the above logic (at least intuitively), so the warning shouldn't be reported.

Of course, I can restructure the control flow easily to avoid this issue, but I still thought it is worth reporting here.
Comment 1 Stephan Herrmann CLA 2016-06-11 15:59:52 EDT
Hi Lukas,

Your intuition is good, but you used a reasoning device, which unfortunately is beyond the compiler: correlation analysis, i.e., reasoning based on correlation between several variables. Example: "o1 is non-null on all branches where o2 is null".

The design of null-flow-analysis (done before my time) allocates 4 bits for each variable. With smart combinatory formulas this achieves a very low performance penalty, allowing us to run this flow analysis as-you-type.

Correlation analysis requires a much more heavy-weight machinery, which is a no-go for an "interactive" compiler.

=> While a reasonable request from a user's p.o.v. JDT doesn't plan to invest in this field ...

Here's a query showing similar requests from the past: https://bugs.eclipse.org/bugs/buglist.cgi?classification=Eclipse&component=Core&product=JDT&query_format=advanced&short_desc=%5Bnull%5D%5Bcorrelation%5D&short_desc_type=allwordssubstr
Comment 2 Lukas Eder CLA 2016-06-12 01:18:36 EDT
Thanks for the feedback. I was afraid this wasn't possible to do in a reasonable amount of time.

I'll just turn off all such warnings for the whole class. Too bad, though. The warning is usually quite useful.
Comment 3 Stephan Herrmann CLA 2016-06-12 05:04:12 EDT
(In reply to Lukas Eder from comment #2)
> Thanks for the feedback. I was afraid this wasn't possible to do in a
> reasonable amount of time.

More background information: our flow analysis is originally designed to check definite assignment according to JLS. Compare by leaving o2 uninitialized in its declaration: compiler will answer:
----------
1. ERROR in /tmp/Test.java (at line 25)
        System.out.println(o2.toString());
                           ^^
The local variable o2 may not have been initialized
----------

Also here you will disagree, but this error is mandated by JLS.
This is essentially the same level of sophistication that you can also expect from null-flow-analysis.
 
> I'll just turn off all such warnings for the whole class. Too bad, though.
> The warning is usually quite useful.


Thanks, yes, it is certainly our goal to avoid situations where users feel urged to suppress this warning. If you find a narrow scope for @SuppressWarnings("null") then this may be exactly the purpose of that mechanism. E.g.,:
        @SuppressWarnings("null") // I manually checked that ... 
        @NonNull Object o2 = null;

Otherwise, I'd argue that a code style that doesn't need correlation for analysis is also easier to understand by humans, e.g., just change:
      case C:
           o1 = "c";
           break;
to
      case C:
           o1 = "c";
           o2 = o1;
           break;
and remove the conditional assignment to o2 below.
Now, both humans and compilers will easily see that o2 is initialized in all branches that complete normally. Isn't that also better separation of concerns: there are things to be done differently depending on e (those go into the switch-case) and things that happen always (outside the switch)?

Of course I don't know about additional intricacies in your original code and of course the preferred style is your decision.
Comment 4 Lukas Eder CLA 2016-06-27 11:47:03 EDT
> More background information: our flow analysis is originally designed to
> check definite assignment according to JLS. Compare by leaving o2
> uninitialized in its declaration: compiler will answer:
> ----------
> 1. ERROR in /tmp/Test.java (at line 25)
>         System.out.println(o2.toString());
>                            ^^
> The local variable o2 may not have been initialized
> ----------
> 
> Also here you will disagree, but this error is mandated by JLS.
> This is essentially the same level of sophistication that you can also
> expect from null-flow-analysis.

Hmm, indeed, interestingly, this makes more sense to me, intuitively. Perhaps because I'm used to this kind of error message rationale?

Ultimately, you're right. Changing the style for humans/compilers to be easier to parse will be the solution both in my example code, and in the "real" code. The "real" code is just quite a bit more complex, so I was hoping for a different answer here :) But let's see this compiler limitation as a warning for bad code style.

Thanks for your explanations!
Comment 5 Lukas Eder CLA 2016-06-27 11:47:38 EDT
BTW: Feel free to close this as won't fix...
Comment 6 Stephan Herrmann CLA 2016-06-28 17:18:04 EDT
Bulk closing all compiler bugs tagged [null][correlation], because we have no plans to add such a feature: it would be a tremendous implementation effort, beyond our current man power, and may be impossible to achieve within the desired performance bounds.

If s.o. has a viable strategy or even implementation for such a feature, I'm all ears.
Comment 7 Jay Arthanareeswaran CLA 2016-08-03 07:58:24 EDT
Verified for 4.7 M1.
Comment 8 Stephan Herrmann CLA 2018-08-30 10:31:04 EDT
I created a new umbrella RFE outlining what would be needed to address this issue.

*** This bug has been marked as a duplicate of bug 538421 ***