Bug 560076 - [null] UnconditionalFlowInfo.isDefinitelyNull(...) throws
NullPointerException
Change-Id: I9939a2a604bed2b5216f34344555b350be8765d0
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index f2f63d8..71a25a3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -6548,4 +6548,44 @@
},
options);
}
+public void testBug560076() {
+ runNegativeTest(
+ new String[] {
+ "org/sqlite/database/sqlite/SQLiteOpenHelper.java",
+ "package org.sqlite.database.sqlite;\n" +
+ "\n" +
+ "public abstract class SQLiteOpenHelper {\n" +
+ " private void getDatabaseLocked(String name, SQLiteDatabase mDatabase) {\n" +
+ " SQLiteDatabase sQLiteDatabase4 = mDatabase;\n" +
+ " try {\n" +
+ " sQLiteDatabase4 = name == null ? null : openDatabase();\n" +
+ " } catch (Throwable e) {\n" +
+ " sQLiteDatabase4 = openDatabase();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " public static SQLiteDatabase openDatabase() {\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "final class SQLiteDatabase implements java.io.Closeable {\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in org\\sqlite\\database\\sqlite\\SQLiteOpenHelper.java (at line 4)\n" +
+ " private void getDatabaseLocked(String name, SQLiteDatabase mDatabase) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "The method getDatabaseLocked(String, SQLiteDatabase) from the type SQLiteOpenHelper is never used locally\n" +
+ "----------\n" +
+ "2. ERROR in org\\sqlite\\database\\sqlite\\SQLiteOpenHelper.java (at line 13)\n" +
+ " public static SQLiteDatabase openDatabase() {\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "This method must return a result of type SQLiteDatabase\n" +
+ "----------\n" +
+ "3. ERROR in org\\sqlite\\database\\sqlite\\SQLiteOpenHelper.java (at line 17)\n" +
+ " final class SQLiteDatabase implements java.io.Closeable {\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "The type SQLiteDatabase must implement the inherited abstract method Closeable.close()\n" +
+ "----------\n");
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index cd5f8c8..ff213b9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -140,6 +140,11 @@
flowInfo.markNullStatus(this.binding, nullStatus); // mark that this flow has seen the resource
}
+ private void attachTo(LocalVariableBinding local) {
+ local.closeTracker = this;
+ this.originalBinding = local;
+ }
+
@Override
public void generateCode(BlockScope currentScope, CodeStream codeStream)
{ /* NOP - this variable is completely dummy, ie. for analysis only. */ }
@@ -574,7 +579,7 @@
break rhsAnalyis;
}
}
- local.closeTracker = rhsTrackVar; // d.: conflicting LHS and RHS, proceed with recordErrorLocation below
+ rhsTrackVar.attachTo(local); // d.: conflicting LHS and RHS, proceed with recordErrorLocation below
}
// keep close-status of RHS unchanged across this assignment
} else if (previousTracker != null) { // 2. re-use tracking variable from the LHS?
@@ -600,7 +605,7 @@
} else { // 3. no re-use, create a fresh tracking variable:
rhsTrackVar = analyseCloseableExpression(flowInfo, flowContext, local, location, rhs, null);
if (rhsTrackVar != null) {
- local.closeTracker = rhsTrackVar;
+ rhsTrackVar.attachTo(local);
// a fresh resource, mark as not-closed:
if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR)) == 0)
flowInfo.markAsDefinitelyNull(rhsTrackVar.binding);