Bug 154995 - [compiler][null] false positive in embedded while/while/break code
Summary: [compiler][null] false positive in embedded while/while/break code
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: 3.3 M3   Edit
Assignee: Maxime Daniel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 157154
  Show dependency tree
 
Reported: 2006-08-24 03:40 EDT by Klaus Reimer CLA
Modified: 2006-10-30 14:08 EST (History)
1 user (show)

See Also:


Attachments
Fix plus test case. (10.27 KB, patch)
2006-09-26 07:50 EDT, Maxime Daniel CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Klaus Reimer CLA 2006-08-24 03:40:00 EDT
We found a situation in our code where the new Null-Pointer warning of Eclipse 3.2 gave a false-positive. In [1] Eclipse says that "e" can't be null. So we naivly removed the null pointer check and our application was no longer working. I have removed as much of the code as possible to find the root of the problem and ended up with this code:

    public void test(String p)
    {
        List<String> list = new ArrayList<String>();
        Iterator<String> it = list.iterator();

        while (it.hasNext())
        {
            String e = it.next();
            e.toString();

            while (true)
            {
                if (it.hasNext()) // [2]
                    e = it.next();
                else
                    e = null;

                if (e == null || p != null) // [3]
                {
                    if (e != null) // [1]
                    {
                        // Do something
                    }
                    break;
                }
            }
        }
    }

The code is total nonsense now but it demonstrates the problem. It is definetly possible that e is null in [1]. If no more elements are in the array when we reach [2] then e is set to null and the if statement in [3] resolves to true. When we trust in the warning then we remove the null pointer check [1] and end up with null-pointer exceptions because e can be null. That's exactly what caused the problem in our application after removing the null-pointer check to resolve the warning.

I'm not sure what confuses the parser here. If I remove the break, the warning is gone. If I remove one of the while loops, the warning is gone, too. Sorry, that I was not able to shorten the code more.
Comment 1 Maxime Daniel CLA 2006-08-24 13:03:45 EDT
Reproduced.

Does not involve Iterator per se. The following test case illustrates the issue. Commenting out lines a or b gets rid of the problem.

public class X {
    public void test(String p, String q, boolean b)
    {
        while (b)
        {
            String e = q;
            e.trim(); // a
            while (true)
            {
                if (b)
                    e = q;
                else
                    e = null;
                if (e == null || p != null)
                {
                    if (e != null)
                    {
                        // Do something
                    }
                    break; // b
                }
            }
        }
    }
}
Comment 2 Maxime Daniel CLA 2006-09-26 07:48:27 EDT
This comes from the fact that we do not leverage fully the available information at the testing point. At line [1], the inner flow info tells us that e may be null or non null. Hence we should not report it to enclosing contexts as needing further verification against the 'can only be null' condition.
Added NullReferenceTest # 457.
Comment 3 Maxime Daniel CLA 2006-09-26 07:50:55 EDT
Created attachment 50898 [details]
Fix plus test case.

The patch essentially avoids to report a variable for checking against can only be null or cannot be null when it is both potentially null and potentially non null (the code already avoided the reporting when the variable was potentially unknown, but this was not enough).
Comment 4 Maxime Daniel CLA 2006-09-26 08:01:56 EDT
Released for 3.3 M3.
Comment 5 Olivier Thomann CLA 2006-10-30 14:08:53 EST
Verified for 3.3 M3 using warm-up build I20061030-0800