Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 370424 - [compiler][null] throw-catch analysis for null flow could be more precise
Summary: [compiler][null] throw-catch analysis for null flow could be more precise
Status: CLOSED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.8   Edit
Hardware: Other Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2012-02-02 06:31 EST by Stephan Herrmann CLA
Modified: 2020-06-05 18:26 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2012-02-02 06:31:16 EST
void fooNull(LineNumberReader lineReader) throws IOException, MyException {
	Object o = null;
	try {
	    while (lineReader.readLine() != null) {
		o = new Object();
		callSome();  // only this can throw MyException
	    }
	} catch (MyException e) {
		o.toString(); // bogus Pot. NPE warning
	}
}
private void callSome() throws MyException {}

Here we report a pot. NPE although that specific catch block can only be reached with o != null.

I'm not sure if the throw-catch analysis has enough information to improve here, but we should have a look.
Comment 1 Ayushman Jain CLA 2012-02-02 07:08:49 EST
For a checked exception this should work fine, but seems like the loop introduces some complexity. See that this already works

void fooNull(LineNumberReader lineReader) throws IOException, MyException {
    Object o = null;
    try {
        o = new Object();
        callSome();  // only this can throw MyException
    } catch (MyException e) {
        o.toString(); // bogus Pot. NPE warning
    }
}
Comment 2 Stephan Herrmann CLA 2012-02-04 10:40:47 EST
Here's another fishy example:

	void experiment1(boolean b) {
		Object o = null;
		try {
			System.out.println("read");
		} finally {
			o = new Object();
		}
		if (o == null) // (A)
			System.out.println("null");
		try {
			if (b) throw new IOException();
			try {
			} finally {
				if (b) throw new IOException();
			}
		} catch (IOException re) {
		}
		if (o == null) // (B)
			System.out.println("null");
	}

At (A) we know that o cannot be null so we warn and next line is flagged dead.

At (B) we no longer have this knowledge, despite that fact that o hasn't been touched between the two locations.

If I change IOException to RuntimeException I see the same problems at (A) and (B).

Currently, this forces me to ignore POTENTIALLY_NONNULL during resource analysis, because ResourceLeakTest#test056n() would give a false positive. Inversely, test064() must currently remain silent, although a pot.leak warning would be correct.

Code-ref: In TryStatement#analyseCode() we have two blocks checking for isUncheckedCatchBlock(i). The difference between these two blocks doesn't seem 100% kosher.

Related to the above?
Comment 3 Stephan Herrmann CLA 2012-02-04 10:53:00 EST
(In reply to comment #2)
> Inversely, test064() must currently remain silent, although a pot.leak warning
> would be correct.

Delete that part. This test (which I haven't even published yet..) incorrectly produced POTENTIALLY_NONNULL, which meanwhile I could fix to producing POTENTIALLY_NULL and all is well on that side. The main issue of comment 2 remains, though.
Comment 4 Stephan Herrmann CLA 2012-07-25 18:16:18 EDT
x-ref: in bug 345305 I started experiments which *might* be related to this issue.
Comment 5 Stephan Herrmann CLA 2014-11-29 11:11:18 EST
See bug 453483 comment 5, to be handled here.
Comment 6 Stephan Herrmann CLA 2014-11-30 17:17:09 EST
Another candidate: bug 195638 comment 10.
Comment 7 Stephan Herrmann CLA 2016-03-25 10:29:08 EDT
Too much on my plate for 4.6. Bulk deferral to 4.7
Comment 8 Stephan Herrmann CLA 2017-05-16 12:05:07 EDT
Ran out of time for 4.7. Bulk move to 4.8.
Comment 9 Manoj N Palat CLA 2018-05-16 12:56:26 EDT
bulk move out of 4.8