### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java,v retrieving revision 1.48 diff -u -r1.48 UnconditionalFlowInfo.java --- compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 9 Feb 2006 16:01:30 -0000 1.48 +++ compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java 17 Feb 2006 09:36:03 -0000 @@ -1510,6 +1510,24 @@ return count; } +/** + * Erase definite inits and potential inits from this, then return this. + * @return this flow info, minus definite inits and potential inits + */ +public UnconditionalFlowInfo nullInfo() { + if (this == DEAD_END) { + return this; + } + this.definiteInits = + this.potentialInits = 0; + if (this.extra != null) { + for (int i = 0, length = this.extra[0].length; i < length; i++) { + this.extra[0][i] = this.extra[1][i] = 0; + } + } + return this; +} + public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() { if (this == DEAD_END) { return this; Index: compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java,v retrieving revision 1.48 diff -u -r1.48 AssertStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 31 Jan 2006 11:19:01 -0000 1.48 +++ compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java 17 Feb 2006 09:36:02 -0000 @@ -54,9 +54,11 @@ boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true; boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false; - UnconditionalFlowInfo assertInfo = assertExpression. - analyseCode(currentScope, flowContext, flowInfo.copy()). + FlowInfo assertRawInfo = assertExpression. + analyseCode(currentScope, flowContext, flowInfo.copy()); + UnconditionalFlowInfo assertWhenTrueInfo = assertRawInfo.initsWhenTrue(). unconditionalInits(); + UnconditionalFlowInfo assertInfo = assertRawInfo.unconditionalCopy(); if (isOptimizedTrueAssertion) { assertInfo.setReachMode(FlowInfo.UNREACHABLE); } @@ -80,8 +82,13 @@ } if (isOptimizedFalseAssertion) { return flowInfo; // if assertions are enabled, the following code will be unreachable + // change this if we need to carry null analysis results of the assert + // expression downstream } else { - return flowInfo.mergedWith(assertInfo); + return flowInfo.mergedWith(assertInfo.nullInfoLessUnconditionalCopy()). + addInitializationsFrom(assertWhenTrueInfo.nullInfo()); + // keep the merge from the initial code for the definite assignment + // analysis, tweak the null part to influence nulls downstream } } #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java,v retrieving revision 1.8 diff -u -r1.8 NullReferenceTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 10 Feb 2006 09:47:41 -0000 1.8 +++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 17 Feb 2006 09:36:06 -0000 @@ -5093,6 +5093,163 @@ "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127244 +// [compiler] Null reference analysis doesn't understand assertions +public void test0950_assert() { + if (COMPLIANCE_1_3.compareTo(this.complianceLevel) < 0) { + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(Object o) {\n" + + " boolean b = o != null;\n" + // shades doubts upon o + " assert(o != null);\n" + // protection + " o.toString();\n" + // quiet + " }\n" + + "}\n"}, + ""); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127244 +// [compiler] Null reference analysis doesn't understand assertions +public void test0951_assert() { + if (COMPLIANCE_1_3.compareTo(this.complianceLevel) < 0) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(Object o) {\n" + + " assert(o == null);\n" + // forces null + " o.toString();\n" + // can only be null + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " o.toString();\n" + + " ^\n" + + "The variable o can only be null; it was either set to null or checked for null when last used\n" + + "----------\n"); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127244 +// [compiler] Null reference analysis doesn't understand assertions +public void test0952_assert() { + if (COMPLIANCE_1_3.compareTo(this.complianceLevel) < 0) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(Object o, boolean b) {\n" + + " assert(o != null || b);\n" + // shade doubts + " o.toString();\n" + // complain + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " o.toString();\n" + + " ^\n" + + "The variable o may be null\n" + + "----------\n"); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127244 +// [compiler] Null reference analysis doesn't understand assertions +public void test0953_assert_combined() { + if (COMPLIANCE_1_3.compareTo(this.complianceLevel) < 0) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(Object o1, Object o2) {\n" + + " assert(o1 != null && o2 == null);\n" + + " if (o1 == null) { };\n" + // complain + " if (o2 == null) { };\n" + // complain + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " if (o1 == null) { };\n" + + " ^^\n" + + "The variable o1 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " if (o2 == null) { };\n" + + " ^^\n" + + "The variable o2 can only be null; it was either set to null or checked for null when last used\n" + + "----------\n"); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127244 +// [compiler] Null reference analysis doesn't understand assertions +public void test0954_assert_fake_reachable() { + if (COMPLIANCE_1_3.compareTo(this.complianceLevel) < 0) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(Object o) {\n" + + " assert(false && o != null);\n" + + " if (o == null) { };\n" + // quiet + " }\n" + + "}\n"}, + ""); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127244 +// [compiler] Null reference analysis doesn't understand assertions +public void test0955_assert_combined() { + if (COMPLIANCE_1_3.compareTo(this.complianceLevel) < 0) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo(Object o) {\n" + + " assert(false || o != null);\n" + + " if (o == null) { };\n" + // complain + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " if (o == null) { };\n" + + " ^\n" + + "The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + + "----------\n"); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127244 +// [compiler] Null reference analysis doesn't understand assertions +public void test0956_assert_combined() { + if (COMPLIANCE_1_3.compareTo(this.complianceLevel) < 0) { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " void foo() {\n" + + " Object o = null;\n" + + " assert(o != null);\n" + // complain + " if (o == null) { };\n" + // complain + " }\n" + + "}\n"}, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " assert(o != null);\n" + + " ^\n" + + "The variable o can only be null; it was either set to null or checked for null when last used\n" + + "----------\n" + + "2. ERROR in X.java (at line 5)\n" + + " if (o == null) { };\n" + + " ^\n" + + "The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + + "----------\n"); + } +} + // null analysis -- notNull protection tag public void _test0900_notNull_protection_tag() { this.runNegativeTest(