| Summary: | [compiler][null][correlation] variables correlation (lack of) | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Eugene Kuleshov <ekuleshov> |
| Component: | Core | Assignee: | Ayushman Jain <amj87.iitr> |
| Status: | CLOSED DUPLICATE | QA Contact: | |
| Severity: | enhancement | ||
| Priority: | P5 | CC: | bugzilla, stephan.herrmann |
| Version: | 3.2 | Keywords: | helpwanted |
| Target Milestone: | 4.7 M1 | ||
| Hardware: | PC | ||
| OS: | All | ||
| Whiteboard: | |||
Here is another case for false positives:
private void aa() {
Object o = null;
while(o==null) {
o = getSomething();
if (o != null) return;
}
}
private Object getSomething() {
return null;
}
Variable o in "while" condition reported as "can only be null", but it is too general assumption because method getSomething() can return different values on every next call (especially ifhere is some multithreading envolved).
(In reply to comment #1) > Here is another case for false positives: > private void aa() { > Object o = null; > while(o==null) { > o = getSomething(); > if (o != null) return; > } > } > private Object getSomething() { > return null; > } > Variable o in "while" condition reported as "can only be null", but it is too > general assumption because method getSomething() can return different values on > every next call (especially ifhere is some multithreading envolved). But whenever getSomething returns a non null, you return, never seing the while condition again. Which implies that o is always null when you hit the while condition. (In reply to comment #2) > But whenever getSomething returns a non null, you return, never seing the while > condition again. Which implies that o is always null when you hit the while > condition. The thing is that getSomething() could return null on first call and non-null on a second. You ca'nt assume that getSomething() always return the same value. Such assumption probably would work for if statement but here is a "while" loop. (In reply to comment #3) > (In reply to comment #2) > The thing is that getSomething() could return null on first call and non-null > on a second. You ca'nt assume that getSomething() always return the same value. > Such assumption probably would work for if statement but here is a "while" > loop. Because of the return, there is a twist though. Stepping through it with null, then non null results, numbering the lines as: 1 Object o = null; 2 while(o==null) { 3 o = getSomething(); 4 if (o != null) return; 5 } 6 start at line 1, set o to null 2 - o is null, goto 3 3 - o gets null per first call 4 - o is null, goto 5 5 - goto 2 2 - o is null, goto 3 3 - o gets non null per second call 4 - o is non null, return Hence line 3 always sees o as null... or do I miss something? (In reply to comment #4) > Because of the return, there is a twist though. > Stepping through it with null, then non null results, numbering the lines as: > 1 Object o = null; > 2 while(o==null) { > 3 o = getSomething(); > 4 if (o != null) return; > 5 } > 6 > > start at line 1, set o to null > 2 - o is null, goto 3 > 3 - o gets null per first call > 4 - o is null, goto 5 > 5 - goto 2 > 2 - o is null, goto 3 > 3 - o gets non null per second call > 4 - o is non null, return > > Hence line 3 always sees o as null... or do I miss something? Ahh. I see what are you mean. The condition in a where clasuse could be replaced with "true". So, it would be nice if error message would try to point that out. It should probably say that "condition is always true" or something like that. Here is another one I don't understand.
private void aa() {
for(int i = 0; i < 10; i++) {
String s = get();
if(s != null) {
for(int j = 0; j < 1; j++) {
break;
}
s.length();
}
}
}
private String get() {
return null;
}
Eclipse is reporting "The variable s may be null" at s.lenght() and it seems has something todo with "break"...
Reproduced. Would you please file a separate bug? (In reply to comment #7) > Reproduced. Would you please file a separate bug? Here it is https://bugs.eclipse.org/bugs/show_bug.cgi?id=129371 Coming back to the initial description.
Avoiding the false reports would involve variables correlation, which is not in scope for 3.2. We may consider this again afterwards.
A workaround gets rid of the extraneous messages though:
public int compare(Object o1, Object o2) {
int rv = 0;
if (o1 == null && o2 == null) {
rv = 0;
} else if (o1 == null) { // o2 != null implied
rv = -1;
} else if (o2 == null) { // o1 != null implied
rv = 1;
} else {
int lhs = ((ExecutionCacheStatistics) o1).numHits();
int rhs = ((ExecutionCacheStatistics) o2).numHits();
rv = lhs - rhs;
}
return rv;
}
Added NullReferenceTest #337 (that won't pass until we implement variables correlation) and #338 (workaround).
Reopening as P5 (since RESOLVED LATER is deprecated). I encountered another similar problem in Ganymedes yesterday.
InputStream is = new FileInputStream(file);
ZipInputStream zis = new ZipInputStream(is);
Database database = null;
try
{
database = getDatabaseConnection(); // can throw SQLException, but not return null
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) // can throw IOException
{
String name = entry.getName();
if (name.toLowerCase().endsWith(".csv"))
{
name = name.substring(0, name.length() - 4);
}
IVRTable table = (IVRTable)tables.get(name);
if (table == null)
{
throw new IOException(name + " is not a valid table");
}
table.open(zis); // can throw IOException
database.deleteAll(table); // can throw SQLException
database.insertAll(table); // can throw SQLException and IOException
}
database.commit(); // can throw SQLException
}
catch (IOException e)
{
if (database != null) // PROBLEM!! according to Eclipse, database is always null
{
database.rollback();
}
throw e;
}
catch (SQLException e)
{
if (database != null)
{
database.rollback();
}
throw e;
}
finally
{
if (database != null)
{
database.disconnect();
}
zis.close();
}
Now I've checked this for 15 minutes, but I'm quite possitive that at that position, database will in fact never be null if getDatabaseConnection() never returns null. If not, it can both be null and non-null, so the check is valid.
See also the reply by Mark Vedder in this thread at JavaRanch:
http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=33&t=027838&p=1
Bulk closing all compiler bugs tagged [null][correlation], because we have no plans to add such a feature: it would be a tremendous implementation effort, beyond our current man power, and may be impossible to achieve within the desired performance bounds. If s.o. has a viable strategy or even implementation for such a feature, I'm all ears. Verified for 4.7 M1 I created a new umbrella RFE outlining what would be needed to address this issue. *** This bug has been marked as a duplicate of bug 538421 *** |
Null reference analyzer in 3.2M5 reports that variables o1 and o2 may be null in the following code (last conditional branch). public int compare(Object o1, Object o2) { int rv = 0; if (o1 == null && o2 != null) { rv = -1; } else if (o1 == null && o2 == null) { rv = 0; } else if (o1 != null && o2 == null) { rv = 1; } else { int lhs = ((ExecutionCacheStatistics) o1).numHits(); // may be null int rhs = ((ExecutionCacheStatistics) o2).numHits(); rv = lhs - rhs; } return rv; } The same false positive reported if retun is used in first 3 conditional branches.