Bug 123399 - [compiler][null] missing null ref warning upon specific if/do while case
Summary: [compiler][null] missing null ref warning upon specific if/do while case
Status: VERIFIED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Linux
: P5 normal (vote)
Target Milestone: 3.7 M4   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-11 04:42 EST by Maxime Daniel CLA
Modified: 2010-12-07 02:00 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Maxime Daniel CLA 2006-01-11 04:42:47 EST
On 3.2M4 plus patch from bug 110030.
The following case (NullReferenceTest #612):
public class X {
  void foo(Object doubt) {
    Object o = null;
    do {
      if (o == null) { // complain: can only be null
        return;
      }
      o = doubt;
    } while (true);
  }
}
does not yield the expected message (silent instead).
Most promising path would probably be to better exploit the return information.
Comment 1 Maxime Daniel CLA 2006-03-21 10:54:40 EST
The issue here is that we need to either 'guess' that we have a return downstream, which we cannot do without a second pass, or to store enough information and to carry it up to the return statement, so as to recombine the upstream information and complain if appropriate.
The former is forbidden by design (we want a single pass).
The latter calls for more than the flow info at the return point (else we would not know where the test occurs, only that o is - again - non null). The information held by the looping context should be specific enough, but we need a copy to avoid complaining on downstream points. Alternatively, we could check the upstream flow info against the current looping context contents whenever we reach a statement that jumps out of the loop.
I'll do an experiment following that path.
Comment 2 Maxime Daniel CLA 2006-03-21 12:00:11 EST
Entered test cases NullReferenceTest #452 (shows that the problem happens with while loops as well) and #453 (see below).
The problem with the approach of comment #1 is that conditional branches change which parts of the looping context can be used to trigger errors. In the case illustrated below, only the test on o2 should yield a message. Yet, until we consider stacking a context for the if(o1 == null) test, there is no means by which we could differentiate the test on o1 from the test on o2 at the context level.

public class X {
  void foo(Object doubt, boolean b) {
    Object o1 = null, o2 = null;
    while (true) {
      if (o2 == null) { /* empty */ } // quiet: can be null or doubt
      if (o1 == null) { // complain: can only be null
        return;
      }
      o1 = o2 = doubt;
    }
  }
}

Many variants could be written that show that we miss some information that would have both the long lifecycle of flow contexts *and* the precision relatively to code paths of flow infos. Adding supplementary context instances for all branches may help, but at a dear cost.
Comment 3 Maxime Daniel CLA 2006-09-26 08:40:05 EDT
Added NullReferenceTest # 614 and 615 that show that all deep exits exhibit the same problem.

Philippe, I would recommand a wontfix here, since this calls for complex solutions that other static analysis tools are better equiped to tackle (especially regarding the number of passes). What do you think?
Comment 4 Maxime Daniel CLA 2007-06-19 08:05:15 EDT
Reopening as P5 (since RESOLVED LATER is deprecated).
Comment 5 Stephan Herrmann CLA 2010-11-18 17:49:55 EST
Here's a null issue that was forgotten a while ago.
Ayush, do we want to close as WONTFIX (see comment 3)?
Comment 6 Ayushman Jain CLA 2010-11-22 01:02:33 EST
(In reply to comment #5)
> Here's a null issue that was forgotten a while ago.
> Ayush, do we want to close as WONTFIX (see comment 3)?

Thanks for pointing it out Stephan. I think Maxime has already spent time working on this and as can be seen, a comprehensive solution is not possible without a second pass (which we dont want), or more contexts.

Unless, you think you can investigate this, or have something in mind, I would recommend a WONTFIX.
Comment 7 Stephan Herrmann CLA 2010-11-23 07:20:58 EST
I agree with the recommendation from comment 3 and comment 6.

Static analysis of loops generally has to consider flows wrapping at the 
bottom of the loop. The pattern discussed in this bug would require that for
particular data flows the analysis "knows" that wrapping cannot occur due
to a return statement between the current statement and the end of the loop.

Given the design decision to implement analysis as a single pass, there
doesn't seem to exist a viable strategy that would effectively connect the
two locations: the location to complain about and the return statement
downstream. Reasoning about returns deeply nested within conditional structures 
and the option to duplicate context information for each condition involved
demonstrate how such strategy would open a big can of worms that the compiler
should better leave to dedicated analysis tools, which, e.g., have the option
to perform any required number of passes.

Closing as WONTFIX.
Comment 8 Ayushman Jain CLA 2010-12-07 02:00:40 EST
Verified with 3.7M4.