Bug 96063 - [compiler] Null pointer analysis needed in autoboxing/autounboxing
Summary: [compiler] Null pointer analysis needed in autoboxing/autounboxing
Status: RESOLVED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-05-20 01:55 EDT by Luke Hutchison CLA
Modified: 2009-08-30 02:33 EDT (History)
4 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 2005-05-20 01:55:10 EDT
Consider the following expression:

  HashMap<String,Integer> m = new HashMap<String,Integer>();
  Integer w = (cond ? 1 : m.get("test"));

If cond is true, this gets evaluated as:

  Integer w = new Integer(1);

If cond is false, this gets evaluated as:

  Integer w = new Integer(m.get("test").intValue());

This throws a NullPointerException.

What would be most intuitive (and more efficient) is if the false case did not
go through the (redundant) autounbox/autobox step, so it evaluated as:

  Integer w = m.get("test");

That would allow the value w to be tested for null after the (?:) step were
complete, however this is disallowed by JLS3 15.25, as confirmed in Bug 95868 by
Philippe Mulet, because since both clauses of the (?:) expr can be treated as
int, the autounboxing must occur.

Therefore I propose that the user be warned in this situation (where an
execution branch must be autounboxed, but is then re-autoboxed as part of the
same expression) that a NullPointerException may be thrown, and this may not be
what the user expects.  The user could then rewrite the expression as

  Integer w;
  if (cond)
    w = 1;
  else
    w = m.get("test");

Which does not exhibit the problem.  (For the record, I think JLS3 15.25 is
somewhat analogous to the situation where subclauses of a (?:) expression share
a supertype, but must be manually casted to the supertype to avoid a warning or
error about incompatible types.)

The deeper problem is not with the (?:) expression, but consists of at least the
following:
 (1) It may be difficult or impossible to determine if a given subexpression
could potentially return a null expression, especially if a function call is
involved.  I believe this is actually uncomputable (like the stopping problem)
in the general case.

 (2) The problem I describe can also result due to interactions between
autounboxing/autoboxing operations in different expressions, or even different
statements.  In the worst case, this is again generally uncomputable if these
statements are in nonoverlapping scopes (and say depend upon a class field).

Problem (1) could be solved automatically in simple cases, such as (?:). 
Probably you could then extend the Java Collections Framework using annotations
in all other cases, adding an annotation like "@CanReturnNull", to hint to the
IDE that it needs to do null autounbox analysis and possibly report a warning. 
(That actually creates problem (3): detecting execution branches where the user
actually checks if the return value is null, and then supressing further
warnings on those execution branches.  This is a little easier than the other
two though.)

Problem (2) is similar to uninitialized variable detection.  There's an obvious
practical limit to how far you would take this analysis (Java appears to track
all possible execution flows within a method, but not between methods, which is
entirely reasonable).
Comment 1 Philipe Mulet CLA 2005-05-20 06:55:12 EDT
Thanks. Will revisit post 3.1.
Comment 2 Jerome Lanneluc CLA 2005-09-22 13:00:13 EDT
To be investigated for 3.2 M4
Comment 3 Maxime Daniel CLA 2005-11-28 07:51:59 EST
There are two parts to this:
a) relate m.get() upon a newly created map to null;
b) given an Integer i that may be null, warn on the conditional expression because  of the somewhat hidden back and forth boxing conversion.
As far as today, none of these is supported by bug 110030. Some of the boxing/unboxing issues are supported though (see NullReferenceTest#test0040 through test0044).
Comment 4 Maxime Daniel CLA 2006-03-21 10:29:27 EST
Since inter-procedural analysis is not in 3.2 scope, this should be deferred.
Comment 5 Eclipse Webmaster CLA 2009-08-30 02:33:51 EDT
As of now 'LATER' and 'REMIND' resolutions are no longer supported.
Please reopen this bug if it is still valid for you.