update to v_B42
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index b1b84c2..9420574 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -1720,7 +1720,6 @@
" maskedCatchBlock\n" +
" includeAssertNull raise null warnings for variables\n" +
" that got tainted in an assert expression\n" +
- " incomplete-switch same as enumSwitch\n" +
" indirectStatic indirect reference to static member\n" +
//OT:
" inferredcallout + a callout binding has to be inferred (OTJLD 3.1(j))\n" +
@@ -1758,6 +1757,8 @@
" syntheticAccess synthetic access for innerclass\n" +
" tasks(<tags separated by |>) tasks identified by tags inside comments\n" +
" typeHiding + type parameter hiding another type\n" +
+ " unavoidableGenericProblems + ignore unavoidable type safety problems\n" +
+ " due to raw APIs\n" +
" unchecked + unchecked type operation\n" +
" unnecessaryElse unnecessary else clause\n" +
" unqualifiedField unqualified reference to field\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
index d961b54..fbb9f44 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -360,129 +360,133 @@
String expectedOutput =
" // Method descriptor #15 ([Ljava/lang/String;)V\n" +
- " // Stack: 3, Locals: 4\n" +
- " public static void main(java.lang.String[] args);\n" +
- " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 3 ldc <String \"1\"> [22]\n" +
- " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 8 aconst_null\n" +
- " 9 goto 13\n" +
- " 12 aconst_null\n" +
- " 13 aconst_null\n" +
- " 14 goto 18\n" +
- " 17 aconst_null\n" +
- " 18 if_acmpne 29\n" +
- " 21 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 24 ldc <String \"2\"> [30]\n" +
- " 26 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 29 new java.lang.StringBuffer [32]\n" +
- " 32 dup\n" +
- " 33 ldc <String \"[\"> [34]\n" +
- " 35 invokespecial java.lang.StringBuffer(java.lang.String) [36]\n" +
- " 38 aconst_null\n" +
- " 39 invokevirtual java.lang.StringBuffer.append(java.lang.Object) : java.lang.StringBuffer [38]\n" +
- " 42 ldc <String \"]\"> [42]\n" +
- " 44 invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [44]\n" +
- " 47 invokevirtual java.lang.StringBuffer.toString() : java.lang.String [47]\n" +
- " 50 ldc <String \"[null]\"> [51]\n" +
- " 52 if_acmpne 59\n" +
- " 55 iconst_1\n" +
- " 56 goto 60\n" +
- " 59 iconst_0\n" +
- " 60 istore_1 [b]\n" +
- " 61 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 64 ldc <String \"3\"> [53]\n" +
- " 66 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 69 aconst_null\n" +
- " 70 astore_2 [s]\n" +
- " 71 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 74 ldc <String \"4\"> [55]\n" +
- " 76 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 79 ldc <String \"aaa\"> [57]\n" +
- " 81 astore_3 [s2]\n" +
- " 82 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 85 ldc <String \"5\"> [59]\n" +
- " 87 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
- " 90 return\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 3]\n" +
- " [pc: 8, line: 4]\n" +
- " [pc: 21, line: 5]\n" +
- " [pc: 29, line: 6]\n" +
- " [pc: 61, line: 7]\n" +
- " [pc: 69, line: 8]\n" +
- " [pc: 71, line: 9]\n" +
- " [pc: 79, line: 10]\n" +
- " [pc: 82, line: 11]\n" +
- " [pc: 90, line: 12]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 91] local: args index: 0 type: java.lang.String[]\n" +
- " [pc: 61, pc: 91] local: b index: 1 type: boolean\n" +
- " [pc: 71, pc: 91] local: s index: 2 type: java.lang.String\n" +
- " [pc: 82, pc: 91] local: s2 index: 3 type: java.lang.String\n";
+ " // Stack: 3, Locals: 4\n" +
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 3 ldc <String \"1\"> [22]\n" +
+ " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 8 aconst_null\n" +
+ " 9 goto 13\n" +
+ " 12 aconst_null\n" +
+ " 13 aconst_null\n" +
+ " 14 goto 18\n" +
+ " 17 aconst_null\n" +
+ " 18 if_acmpne 29\n" +
+ " 21 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 24 ldc <String \"2\"> [30]\n" +
+ " 26 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 29 new java.lang.StringBuffer [32]\n" +
+ " 32 dup\n" +
+ " 33 ldc <String \"[\"> [34]\n" +
+ " 35 invokespecial java.lang.StringBuffer(java.lang.String) [36]\n" +
+ " 38 aconst_null\n" +
+ " 39 invokevirtual java.lang.StringBuffer.append(java.lang.Object) : java.lang.StringBuffer [38]\n" +
+ " 42 ldc <String \"]\"> [42]\n" +
+ " 44 invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [44]\n" +
+ " 47 invokevirtual java.lang.StringBuffer.toString() : java.lang.String [47]\n" +
+ " 50 ldc <String \"[null]\"> [51]\n" +
+ " 52 if_acmpne 59\n" +
+ " 55 iconst_1\n" +
+ " 56 goto 60\n" +
+ " 59 iconst_0\n" +
+ " 60 istore_1 [b]\n" +
+ " 61 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 64 ldc <String \"3\"> [53]\n" +
+ " 66 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 69 aconst_null\n" +
+ " 70 astore_2 [s]\n" +
+ " 71 aload_2 [s]\n" +
+ " 72 ifnonnull 83\n" +
+ " 75 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 78 ldc <String \"4\"> [55]\n" +
+ " 80 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 83 ldc <String \"aaa\"> [57]\n" +
+ " 85 astore_3 [s2]\n" +
+ " 86 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 89 ldc <String \"5\"> [59]\n" +
+ " 91 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
+ " 94 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 3]\n" +
+ " [pc: 8, line: 4]\n" +
+ " [pc: 21, line: 5]\n" +
+ " [pc: 29, line: 6]\n" +
+ " [pc: 61, line: 7]\n" +
+ " [pc: 69, line: 8]\n" +
+ " [pc: 71, line: 9]\n" +
+ " [pc: 83, line: 10]\n" +
+ " [pc: 86, line: 11]\n" +
+ " [pc: 94, line: 12]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 95] local: args index: 0 type: java.lang.String[]\n" +
+ " [pc: 61, pc: 95] local: b index: 1 type: boolean\n" +
+ " [pc: 71, pc: 95] local: s index: 2 type: java.lang.String\n" +
+ " [pc: 86, pc: 95] local: s2 index: 3 type: java.lang.String\n";
String expectedOutput15 =
" // Method descriptor #15 ([Ljava/lang/String;)V\n" +
- " // Stack: 3, Locals: 4\n" +
- " public static void main(java.lang.String[] args);\n" +
- " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 3 ldc <String \"1\"> [22]\n" +
- " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 8 aconst_null\n" +
- " 9 goto 13\n" +
- " 12 aconst_null\n" +
- " 13 aconst_null\n" +
- " 14 goto 18\n" +
- " 17 aconst_null\n" +
- " 18 if_acmpne 29\n" +
- " 21 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 24 ldc <String \"2\"> [30]\n" +
- " 26 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 29 new java.lang.StringBuilder [32]\n" +
- " 32 dup\n" +
- " 33 ldc <String \"[\"> [34]\n" +
- " 35 invokespecial java.lang.StringBuilder(java.lang.String) [36]\n" +
- " 38 aconst_null\n" +
- " 39 invokevirtual java.lang.StringBuilder.append(java.lang.Object) : java.lang.StringBuilder [38]\n" +
- " 42 ldc <String \"]\"> [42]\n" +
- " 44 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [44]\n" +
- " 47 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [47]\n" +
- " 50 ldc <String \"[null]\"> [51]\n" +
- " 52 if_acmpne 59\n" +
- " 55 iconst_1\n" +
- " 56 goto 60\n" +
- " 59 iconst_0\n" +
- " 60 istore_1 [b]\n" +
- " 61 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 64 ldc <String \"3\"> [53]\n" +
- " 66 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 69 aconst_null\n" +
- " 70 astore_2 [s]\n" +
- " 71 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 74 ldc <String \"4\"> [55]\n" +
- " 76 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
- " 79 ldc <String \"aaa\"> [57]\n" +
- " 81 astore_3 [s2]\n" +
- " 82 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
- " 85 ldc <String \"5\"> [59]\n" +
- " 87 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
- " 90 return\n" +
- " Line numbers:\n" +
- " [pc: 0, line: 3]\n" +
- " [pc: 8, line: 4]\n" +
- " [pc: 21, line: 5]\n" +
- " [pc: 29, line: 6]\n" +
- " [pc: 61, line: 7]\n" +
- " [pc: 69, line: 8]\n" +
- " [pc: 71, line: 9]\n" +
- " [pc: 79, line: 10]\n" +
- " [pc: 82, line: 11]\n" +
- " [pc: 90, line: 12]\n" +
- " Local variable table:\n" +
- " [pc: 0, pc: 91] local: args index: 0 type: java.lang.String[]\n" +
- " [pc: 61, pc: 91] local: b index: 1 type: boolean\n" +
- " [pc: 71, pc: 91] local: s index: 2 type: java.lang.String\n" +
- " [pc: 82, pc: 91] local: s2 index: 3 type: java.lang.String\n";
+ " // Stack: 3, Locals: 4\n" +
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 3 ldc <String \"1\"> [22]\n" +
+ " 5 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 8 aconst_null\n" +
+ " 9 goto 13\n" +
+ " 12 aconst_null\n" +
+ " 13 aconst_null\n" +
+ " 14 goto 18\n" +
+ " 17 aconst_null\n" +
+ " 18 if_acmpne 29\n" +
+ " 21 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 24 ldc <String \"2\"> [30]\n" +
+ " 26 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 29 new java.lang.StringBuilder [32]\n" +
+ " 32 dup\n" +
+ " 33 ldc <String \"[\"> [34]\n" +
+ " 35 invokespecial java.lang.StringBuilder(java.lang.String) [36]\n" +
+ " 38 aconst_null\n" +
+ " 39 invokevirtual java.lang.StringBuilder.append(java.lang.Object) : java.lang.StringBuilder [38]\n" +
+ " 42 ldc <String \"]\"> [42]\n" +
+ " 44 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [44]\n" +
+ " 47 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [47]\n" +
+ " 50 ldc <String \"[null]\"> [51]\n" +
+ " 52 if_acmpne 59\n" +
+ " 55 iconst_1\n" +
+ " 56 goto 60\n" +
+ " 59 iconst_0\n" +
+ " 60 istore_1 [b]\n" +
+ " 61 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 64 ldc <String \"3\"> [53]\n" +
+ " 66 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 69 aconst_null\n" +
+ " 70 astore_2 [s]\n" +
+ " 71 aload_2 [s]\n" +
+ " 72 ifnonnull 83\n" +
+ " 75 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 78 ldc <String \"4\"> [55]\n" +
+ " 80 invokevirtual java.io.PrintStream.print(java.lang.String) : void [24]\n" +
+ " 83 ldc <String \"aaa\"> [57]\n" +
+ " 85 astore_3 [s2]\n" +
+ " 86 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 89 ldc <String \"5\"> [59]\n" +
+ " 91 invokevirtual java.io.PrintStream.println(java.lang.String) : void [61]\n" +
+ " 94 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 3]\n" +
+ " [pc: 8, line: 4]\n" +
+ " [pc: 21, line: 5]\n" +
+ " [pc: 29, line: 6]\n" +
+ " [pc: 61, line: 7]\n" +
+ " [pc: 69, line: 8]\n" +
+ " [pc: 71, line: 9]\n" +
+ " [pc: 83, line: 10]\n" +
+ " [pc: 86, line: 11]\n" +
+ " [pc: 94, line: 12]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 95] local: args index: 0 type: java.lang.String[]\n" +
+ " [pc: 61, pc: 95] local: b index: 1 type: boolean\n" +
+ " [pc: 71, pc: 95] local: s index: 2 type: java.lang.String\n" +
+ " [pc: 86, pc: 95] local: s2 index: 3 type: java.lang.String\n";
if (this.complianceLevel >= ClassFileConstants.JDK1_5) {
int index = actualOutput.indexOf(expectedOutput15);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
index d67fb46..32b50af 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * Copyright (c) 2005, 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
@@ -2246,6 +2246,120 @@
"Dead code\n" +
"----------\n");
}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234
+// Warn uninitialized variable in deadcode if deadcode has been inferred
+// by null analysis
+public void testBug338234a() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " int i;\n" +
+ " String str = null;\n" +
+ " if (str != null)\n" +
+ " i++; \n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 6)\n" +
+ " i++; \n" +
+ " ^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " i++; \n" +
+ " ^\n" +
+ "The local variable i may not have been initialized\n" +
+ "----------\n");
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234
+// Don't warn uninitialized variable in deadcode if deadcode has not been inferred
+// by null analysis
+public void testBug338234b() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " int i;\n" +
+ " l: {\n" +
+ " if(false)\n" +
+ " break l;\n" +
+ " return;\n" +
+ " }\n" +
+ " i++; \n" +
+ " }\n" +
+ "}\n"
+ },
+ "");
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234
+// Warn uninitialized field in deadcode if deadcode has been inferred
+// by null analysis
+public void testBug338234c() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public final int field1;\n" +
+ " {\n" +
+ " int i;\n" +
+ " String str = null;\n" +
+ " if(str != null)\n" +
+ " i = field1;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 1)\n" +
+ " public class X {\n" +
+ " ^\n" +
+ "The blank final field field1 may not have been initialized\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 7)\n" +
+ " i = field1;\n" +
+ " ^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 7)\n" +
+ " i = field1;\n" +
+ " ^^^^^^\n" +
+ "The blank final field field1 may not have been initialized\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234
+// Warn uninitialized field in deadcode if deadcode has been inferred
+// by null analysis
+public void testBug338234d() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void foo(boolean b) {\n" +
+ " int i;\n" +
+ " String str = null;\n" +
+ " if(b){\n" +
+ " if(str == null)\n" +
+ " return;\n" +
+ " } else {\n" +
+ " i = 2;\n" +
+ " }\n" +
+ " i++;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " i++;\n" +
+ " ^\n" +
+ "The local variable i may not have been initialized\n" +
+ "----------\n");
+}
public static Class testClass() {
return FlowAnalysisTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java
index fefb207..23d9410 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InitializationTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
+ * Copyright (c) 2010, 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - contribution for bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -14,6 +15,7 @@
import junit.framework.Test;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
public class InitializationTests extends AbstractRegressionTest {
@@ -393,6 +395,75 @@
"----------\n",
null, false, options);
}
+
+// 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 = true)))\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"
+ },
+ "true");
+}
+
+// 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");
+}
+// Bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
+// must detect that b2 may be uninitialized, no special semantics for Boolean
+public void testBug324178d() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5)
+ return;
+ this.runNegativeTest(
+ new String[] {
+ "Bug324178.java",
+ "public class Bug324178 {\n" +
+ " boolean foo(boolean b1) {\n" +
+ " Boolean b2;\n" +
+ " if (b1 ? (b2 = Boolean.TRUE) : null)\n" +
+ " return b2;\n" +
+ " return false;\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.print(new Bug324178().foo(true));\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in Bug324178.java (at line 5)\n" +
+ " return b2;\n" +
+ " ^^\n" +
+ "The local variable b2 may not have been initialized\n" +
+ "----------\n");
+}
public static Class testClass() {
return InitializationTests.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
index a7b700b..7c776f2 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
@@ -15,6 +15,8 @@
* bug 320170 - [compiler] [null] Whitebox issues in null analysis
* bug 332637 - Dead Code detection removing code that isn't dead
* bug 338303 - Warning about Redundant assignment conflicts with definite assignment
+ * bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+ * bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -42,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[] { "testBug325229" };
+// TESTS_NAMES = new String[] { "testBug339250" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -11780,10 +11782,16 @@
" 2 aconst_null\n" +
" 3 astore_2 [s2]\n" +
" 4 aload_1 [s]\n" +
- " 5 ifnull 12\n" +
+ " 5 ifnull 26\n" +
" 8 aload_2 [s2]\n" +
- " 9 ifnull 12\n" +
- " 12 return\n";
+ " 9 ifnull 26\n" +
+ " 12 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 15 aload_1 [s]\n" +
+ " 16 invokevirtual java.io.PrintStream.println(java.lang.String) : void [22]\n" +
+ " 19 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 22 aload_2 [s2]\n" +
+ " 23 invokevirtual java.io.PrintStream.println(java.lang.String) : void [22]\n" +
+ " 26 return\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
}
@@ -13839,6 +13847,149 @@
"");
}
+// Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+// original issue
+public void testBug336428() {
+ this.runConformTest(
+ new String[] {
+ "DoWhileBug.java",
+ "public class DoWhileBug {\n" +
+ " void test(boolean b1, Object o1) {\n" +
+ " Object o2 = new Object();\n" +
+ " do {\n" +
+ " if (b1)\n" +
+ " o1 = null;\n" +
+ " } while ((o2 = o1) != null);\n" +
+ " }\n" +
+ "}"
+ },
+ "");
+}
+// Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+// hitting the same implementation branch from within the loop
+// information from unknown o1 is not propagated into the loop, analysis currently believes o2 is def null.
+public void _testBug336428a() {
+ this.runConformTest(
+ new String[] {
+ "DoWhileBug.java",
+ "public class DoWhileBug {\n" +
+ " void test(boolean b1, Object o1) {\n" +
+ " Object o2 = null;\n" +
+ " do {\n" +
+ " if (b1)\n" +
+ " o1 = null;\n" +
+ " if ((o2 = o1) != null)\n" +
+ " break;\n" +
+ " } while (true);\n" +
+ " }\n" +
+ "}"
+ },
+ "");
+}
+
+// Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+// in this variant the analysis believes o2 is def unknown and doesn't even consider raising a warning.
+public void _testBug336428b() {
+ this.runNegativeTest(
+ new String[] {
+ "DoWhileBug.java",
+ "public class DoWhileBug {\n" +
+ " void test(boolean b1) {\n" +
+ " Object o1 = null;\n" +
+ " Object o2 = null;\n" +
+ " do {\n" +
+ " if ((o2 = o1) == null) break;\n" +
+ " } while (true);\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in DoWhileBug.java (at line 6)\n" +
+ " if ((o2 = o1) == null) break;\n" +
+ " ^^^^^^^^^\n" +
+ "Redundant null check: The variable o2 can only be null at this location\n" +
+ "----------\n");
+}
+
+// Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+// in this case considering o1 as unknown is correct
+public void testBug336428c() {
+ if (this.complianceLevel >= ClassFileConstants.JDK1_5) {
+ this.runConformTest(
+ new String[] {
+ "DoWhileBug.java",
+ "public class DoWhileBug {\n" +
+ " void test(boolean b1, Object o1) {\n" +
+ " Object o2 = null;\n" +
+ " do {\n" +
+ " if ((o2 = o1) == null) break;\n" +
+ " } while (true);\n" +
+ " }\n" +
+ "}"
+ },
+ "");
+ }
+}
+
+// Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+// one more if-statement triggers the expected warnings
+public void testBug336428d() {
+ this.runNegativeTest(
+ new String[] {
+ "DoWhileBug.java",
+ "public class DoWhileBug {\n" +
+ " void test(boolean b1) {\n" +
+ " Object o1 = null;\n" +
+ " Object o2 = null;\n" +
+ " do {\n" +
+ " if (b1)\n" +
+ " o1 = null;\n" +
+ " if ((o2 = o1) == null) break;\n" +
+ " } while (true);\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in DoWhileBug.java (at line 7)\n" +
+ " o1 = null;\n" +
+ " ^^\n" +
+ "Redundant assignment: The variable o1 can only be null at this location\n" +
+ "----------\n" +
+ "2. ERROR in DoWhileBug.java (at line 8)\n" +
+ " if ((o2 = o1) == null) break;\n" +
+ " ^^^^^^^^^\n" +
+ "Redundant null check: The variable o2 can only be null at this location\n" +
+ "----------\n");
+}
+
+// Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+// same analysis, but assert instead of if suppresses the warning
+public void testBug336428e() {
+ if (this.complianceLevel >= ClassFileConstants.JDK1_5) {
+ this.runNegativeTest(
+ new String[] {
+ "DoWhileBug.java",
+ "public class DoWhileBug {\n" +
+ " void test(boolean b1) {\n" +
+ " Object o1 = null;\n" +
+ " Object o2 = null;\n" +
+ " do {\n" +
+ " if (b1)\n" +
+ " o1 = null;\n" +
+ " assert (o2 = o1) == null : \"bug\";\n" +
+ " } while (true);\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in DoWhileBug.java (at line 7)\n" +
+ " o1 = null;\n" +
+ " ^^\n" +
+ "Redundant assignment: The variable o1 can only be null at this location\n" +
+ "----------\n");
+ }
+}
+
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=332838
// Null info of assert statements should not affect flow info
// when CompilerOptions.OPTION_IncludeNullInfoFromAsserts is disabled.
@@ -14060,4 +14211,323 @@
},
"");
}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234
+public void testBug338234() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " static int foo() {\n" +
+ " Object o = null;\n" +
+ " int i = 0;\n" +
+ " label: {\n" +
+ " if (o == null)\n" +
+ " break label;\n" +
+ " i++;" +
+ " }\n" +
+ " if (i != 0) {\n" +
+ " System.out.println(i);\n" +
+ " }\n" +
+ " return 0;\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " if (o == null)\n" +
+ " ^\n" +
+ "Redundant null check: The variable o can only be null at this location\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 8)\n" +
+ " i++; }\n" +
+ " ^^^\n" +
+ "Dead code\n" +
+ "----------\n");
+}
+// 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
+public void testBug324178a() {
+ this.runConformTest(
+ new String[] {
+ "Bug324178.java",
+ "public class Bug324178 {\n" +
+ " boolean b;\n" +
+ " void foo(Boolean u) {\n" +
+ " if (u == null) {}\n" +
+ " Boolean o;\n" +
+ " o = (u == null) ? Boolean.TRUE : u;\n" +
+ " o.toString(); // Incorrect potential NPE\n" +
+ " }\n" +
+ "}\n"
+ },
+ "");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=326950
+public void testBug326950a() throws Exception {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.WARNING);
+ 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" +
+ " if (s == null) {\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " } else {\n" +
+ " System.out.println(\"Dead code, but don't optimize me out\");\n" +
+ " }\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS",
+ null,
+ true,
+ null,
+ options,
+ null);
+ String expectedOutput =
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 aconst_null\n" +
+ " 1 astore_1 [s]\n" +
+ " 2 aload_1 [s]\n" +
+ " 3 ifnonnull 17\n" +
+ " 6 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 9 ldc <String \"SUCCESS\"> [22]\n" +
+ " 11 invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]\n" +
+ " 14 goto 25\n" +
+ " 17 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 20 ldc <String \"Dead code, but don\'t optimize me out\"> [30]\n" +
+ " 22 invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]\n" +
+ " 25 return\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=326950
+// Code marked dead due to if(false), etc. can be optimized out
+public void testBug326950b() throws Exception {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.WARNING);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " int i = 0;\n" +
+ " if (false) {\n" +
+ " System.out.println(\"Deadcode and you can optimize me out\");\n" +
+ " }\n" +
+ " if (true) {\n" +
+ " i++;\n" +
+ " } else {\n" +
+ " System.out.println(\"Deadcode and you can optimize me out\");\n" +
+ " }\n" +
+ " }\n" +
+ "}",
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+ String expectedOutput =
+ " public static void main(java.lang.String[] args);\n" +
+ " 0 iconst_0\n" +
+ " 1 istore_1 [i]\n" +
+ " 2 iinc 1 1 [i]\n" +
+ " 5 return\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=326950
+// Free return should be generated for a method even if it ends with dead code
+public void testBug326950c() throws Exception {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.WARNING);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void foo(String[] args) {\n" +
+ " String s = \"\";\n" +
+ " int i = 0;\n" +
+ " if (s != null) {\n" +
+ " return;\n" +
+ " }\n" +
+ " i++;\n" +
+ " }\n" +
+ "}",
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+ String expectedOutput =
+ " public void foo(java.lang.String[] args);\n" +
+ " 0 ldc <String \"\"> [16]\n" +
+ " 2 astore_2 [s]\n" +
+ " 3 iconst_0\n" +
+ " 4 istore_3 [i]\n" +
+ " 5 aload_2 [s]\n" +
+ " 6 ifnull 10\n" +
+ " 9 return\n" +
+ " 10 iinc 3 1 [i]\n" +
+ " 13 return\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=326950
+// Free return should be generated for a constructor even if it ends with dead code
+public void testBug326950d() throws Exception {
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportPotentialNullReference, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.WARNING);
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " X() {\n" +
+ " String s = \"\";\n" +
+ " int i = 0;\n" +
+ " if (s != null) {\n" +
+ " return;\n" +
+ " }\n" +
+ " i++;\n" +
+ " }\n" +
+ "}",
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null);
+ String expectedOutput =
+ " X();\n" +
+ " 0 aload_0 [this]\n" +
+ " 1 invokespecial java.lang.Object() [8]\n" +
+ " 4 ldc <String \"\"> [10]\n" +
+ " 6 astore_1 [s]\n" +
+ " 7 iconst_0\n" +
+ " 8 istore_2 [i]\n" +
+ " 9 aload_1 [s]\n" +
+ " 10 ifnull 14\n" +
+ " 13 return\n" +
+ " 14 iinc 2 1 [i]\n" +
+ " 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
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java
index a702bab..3ed50bb 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProgrammingProblemsTest.java
@@ -2309,4 +2309,42 @@
true/*shouldFlushOutputDirectory*/,
customOptions);
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=339139
+// Issue local variable not used warning inside deadcode
+public void test0059() throws Exception {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING);
+ customOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING);
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " Object a = null;\n" +
+ " if (a != null){\n" +
+ " int j = 3;\n" +
+ " j++;\n" + // value is not used
+ " }\n" +
+ " System.out.println(\"OK\");\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 4)\n" +
+ " if (a != null){\n" +
+ " int j = 3;\n" +
+ " j++;\n" +
+ " }\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 5)\n" +
+ " int j = 3;\n" +
+ " ^\n" +
+ "The value of the local variable j is not used\n" +
+ "----------\n",
+ null/*classLibraries*/,
+ true/*shouldFlushOutputDirectory*/,
+ customOptions);
+}
}
\ No newline at end of file