### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java,v retrieving revision 1.98 diff -u -r1.98 ConditionalExpression.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java 14 Jan 2011 17:02:24 -0000 1.98 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java 28 Feb 2011 00:25:00 -0000 @@ -83,8 +83,9 @@ mergedInfo = trueFlowInfo.addPotentialInitializationsFrom(falseFlowInfo); } else if (isConditionOptimizedFalse) { mergedInfo = falseFlowInfo.addPotentialInitializationsFrom(trueFlowInfo); - } else { + } else if (this.resolvedType == TypeBinding.BOOLEAN) { // if ((t && (v = t)) ? t : t && (v = f)) r = v; -- ok + // if (b ? false : (true && (v = false))) return v; -- ok cst = this.optimizedIfTrueConstant; boolean isValueIfTrueOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true; boolean isValueIfTrueOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false; @@ -113,6 +114,8 @@ FlowInfo.conditional( trueInfoWhenTrue.mergedWith(falseInfoWhenTrue), trueInfoWhenFalse.mergedWith(falseInfoWhenFalse)); + } else { + mergedInfo = FlowInfo.conditional(trueFlowInfo, falseFlowInfo); } this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo); @@ -314,8 +317,8 @@ } return this.valueIfFalse.nullStatus(flowInfo); } - int ifTrueNullStatus = this.valueIfTrue.nullStatus(flowInfo), - ifFalseNullStatus = this.valueIfFalse.nullStatus(flowInfo); + int ifTrueNullStatus = this.valueIfTrue.nullStatus(flowInfo.initsWhenTrue()), + ifFalseNullStatus = this.valueIfFalse.nullStatus(flowInfo.initsWhenFalse()); if (ifTrueNullStatus == ifFalseNullStatus) { return ifTrueNullStatus; } Index: compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java,v retrieving revision 1.79 diff -u -r1.79 LocalDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java 8 Feb 2011 05:59:17 -0000 1.79 +++ compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java 28 Feb 2011 00:25:00 -0000 @@ -72,11 +72,9 @@ this.initialization.checkNPE(currentScope, flowContext, flowInfo); } - flowInfo = - this.initialization - .analyseCode(currentScope, flowContext, flowInfo) - .unconditionalInits(); - int nullStatus = this.initialization.nullStatus(flowInfo); + FlowInfo unflattenedInfo = this.initialization.analyseCode(currentScope, flowContext, flowInfo); + flowInfo = unflattenedInfo.unconditionalInits(); + int nullStatus = this.initialization.nullStatus(unflattenedInfo); if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes this.bits |= FirstAssignmentToLocal; } else { #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.113 diff -u -r1.113 NullReferenceTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 27 Feb 2011 21:42:50 -0000 1.113 +++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 28 Feb 2011 00:25:18 -0000 @@ -42,7 +42,7 @@ // Only the highest compliance level is run; add the VM argument // -Dcompliance=1.4 (for example) to lower it if needed static { -// TESTS_NAMES = new String[] { "testBug325229" }; + TESTS_NAMES = new String[] { "testBug324178" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } @@ -14060,4 +14060,60 @@ }, ""); } +// Bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself +public void testBug324178() { + this.runConformTest( + new String[] { + "Bug324178.java", + "public class Bug324178 {\n" + + " boolean b;\n" + + " void foo(Object u) {\n" + + " if (u == null) {}\n" + + " Object o = (u == null) ? new Object() : u;\n" + + " o.toString(); // Incorrect potential NPE\n" + + " }\n" + + "}\n" + }, + ""); +} +// Bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself +// definite assignment along all true-yielding paths is sufficient +public void testBug324178b() { + this.runConformTest( + new String[] { + "Bug324178.java", + "public class Bug324178 {\n" + + " boolean foo(boolean b) {\n" + + " boolean v;\n" + + " if (b ? false : (true && (v = false)))\n" + + " return v;\n" + // OK to read v! + " return false;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(new Bug324178().foo(false));\n" + + " }\n" + + "}\n" + }, + "false"); +} +// Bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself +// definite assignment along all true-yielding paths is sufficient +public void testBug324178c() { + this.runConformTest( + new String[] { + "Bug324178.java", + "public class Bug324178 {\n" + + " boolean foo() {\n" + + " boolean r=false;" + + " boolean v;\n" + + " if ((true && (v = true)) ? true : true && (v = false)) r = v;\n" + + " return r;\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " System.out.print(new Bug324178().foo());\n" + + " }\n" + + "}\n" + }, + "true"); +} } \ No newline at end of file