Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 327485 - [extract local] Refactoring to create local var can create new local outside "if" that tests for null, causing NPE in executed code
Summary: [extract local] Refactoring to create local var can create new local outside...
Status: CLOSED DUPLICATE of bug 133559
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.7   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-11 17:39 EDT by Luke Hutchison CLA
Modified: 2010-12-02 04:55 EST (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 Luke Hutchison CLA 2010-10-11 17:39:25 EDT
Build Identifier: 

When refactoring, an expression can be moved to a position outside an if-statement that guarantees the expression cannot be null, causing NPEs.  For example:


Before refactoring:

	if (node.equivOrigin1 != null && node.equivOrigin2 != null) {
		node.lineagePath = "[" + node.equivOrigin1.lineagePath + "/"
		                       + node.equivOrigin2.lineagePath + "]";
	} else {
		node.lineagePath = node.equivOrigin1 != null
		     ? node.equivOrigin1.lineagePath : node.equivOrigin2.lineagePath;
	}
	// It is impossible for any of the above code to generate a NPE.

After refactoring:

	String ep1 = node.equivOrigin1.lineagePath;  // Can cause NPE here
	String ep2 = node.equivOrigin2.lineagePath;  // ...or here
	if (node.equivOrigin1 != null && node.equivOrigin2 != null) {
		node.lineagePath = "[" + ep1 + "/" + ep2 + "]";
	} else {
		node.lineagePath = node.equivOrigin1 != null ? ep1 : ep2;
	}
	// The above code can generate a NPE.


This is a curly problem that is probably a little hard to catch until Eclipse gets full nullability tracing (which I understand is in general an uncomputable problem given Java's language model?).  However simple cases should be caught, refactoring should never introduce bugs if at all possible...


Reproducible: Always
Comment 1 Luke Hutchison CLA 2010-10-11 17:43:19 EDT
Of course if node.equivOrigin1.lineagePath or node.equivOrigin1.lineagePath is null, the field node.lineagePath will have the substring "null" in it after null is rendered into a string "null" by the string concat operator, but the point is it won't actually generate a NPE before refactoring, but will generate a NPE after, because node.equivOrigin1 or node.equivOrigin2 can now be null during the setting of ep1 or ep2.
Comment 2 Ayushman Jain CLA 2010-10-12 03:01:19 EDT
(In reply to comment #1)
> Of course if node.equivOrigin1.lineagePath or node.equivOrigin1.lineagePath is
> null, the field node.lineagePath will have the substring "null" in it after
> null is rendered into a string "null" by the string concat operator, but the
> point is it won't actually generate a NPE before refactoring, but will generate
> a NPE after, because node.equivOrigin1 or node.equivOrigin2 can now be null
> during the setting of ep1 or ep2.

Moving to JDT/UI for follow up. 
IMO, it doesn't really make much sense to perform a full static analysis on the variable which is being extracted. This will slow down refactoring too much.
Comment 3 Dani Megert CLA 2010-12-02 04:55:06 EST

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