### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java,v retrieving revision 1.60 diff -u -r1.60 CompoundAssignment.java --- compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java 22 Jul 2009 17:08:54 -0000 1.60 +++ compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java 9 Mar 2011 09:41:15 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -42,7 +42,18 @@ if (this.resolvedType.id != T_JavaLangString) { this.lhs.checkNPE(currentScope, flowContext, flowInfo); } - return ((Reference) this.lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits(); + flowInfo = ((Reference) this.lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits(); + if (this.resolvedType.id == T_JavaLangString) { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250 + LocalVariableBinding local = this.lhs.localVariableBinding(); + if (local != null && this.resolvedType.id == T_JavaLangString) { + // compound assignment results in a definitely non null value for String + flowInfo.markAsDefinitelyNonNull(local); + if (flowContext.initsOnFinally != null) + flowContext.initsOnFinally.markAsDefinitelyNonNull(local); + } + } + return flowInfo; } public boolean checkCastCompatibility() { #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.117 diff -u -r1.117 NullReferenceTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 5 Mar 2011 17:18:31 -0000 1.117 +++ src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java 9 Mar 2011 09:41:18 -0000 @@ -44,7 +44,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[] { "testBug336428e" }; +// TESTS_NAMES = new String[] { "testBug339250" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } @@ -14441,4 +14441,93 @@ " 17 return\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250 +// Check code gen +public void testBug339250() throws Exception { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.WARNING); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " String s = null;\n" + + " s += \"correctly\";\n" + + " if (s != null) {\n" + // s cannot be null + " System.out.println(\"It works \" + s);\n" + + " }\n" + + " }\n" + + "}", + }, + "It works nullcorrectly", + null, + true, + null, + options, + null); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250 +// Check that the redundant null check warning is correctly produced +public void testBug339250a() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " String s = null;\n" + + " s += \"correctly\";\n" + + " if (s != null) {\n" + // s cannot be null + " System.out.println(\"It works \" + s);\n" + + " }\n" + + " }\n" + + "}", + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " if (s != null) {\n" + + " ^\n" + + "Redundant null check: The variable s cannot be null at this location\n" + + "----------\n"); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250 +// Check that the redundant null check warning is correctly produced +public void testBug339250b() throws Exception { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public static void main(String[] args) {\n" + + " String s = null;\n" + + " s += null;\n" + + " if (s != null) {\n" + // s is definitely not null + " System.out.println(\"It works \" + s);\n" + + " }\n" + + " s = null;\n" + + " if (s != null) {\n" + // s is definitely null + " System.out.println(\"Fails \" + s);\n" + + " } else {\n" + + " System.out.println(\"Works second time too \" + s);\n" + + " }\n" + + " }\n" + + "}", + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " if (s != null) {\n" + + " ^\n" + + "Redundant null check: The variable s cannot be null at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 9)\n" + + " if (s != null) {\n" + + " ^\n" + + "Null comparison always yields false: The variable s can only be null at this location\n" + + "----------\n" + + "3. WARNING in X.java (at line 9)\n" + + " if (s != null) {\n" + + " System.out.println(\"Fails \" + s);\n" + + " } else {\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n"); +} } \ No newline at end of file