blob: bb3b8b0e0774745b9bd3e6a670ce2e2f21f19e19 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* This is an implementation of an early-draft specification developed under the Java
* Community Process (JCP) and is made available for testing and evaluation purposes
* only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
* bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
* bug 383690 - [compiler] location of error re uninitialized final field should be aligned
* bug 391517 - java.lang.VerifyError on code that runs correctly in Eclipse 3.7 and eclipse 3.6
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
import java.io.File;
import java.util.Map;
import junit.framework.Test;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
@SuppressWarnings({ "unchecked", "rawtypes" })
public class FlowAnalysisTest extends AbstractRegressionTest {
static {
// TESTS_NAMES = new String[] { "testBug380313" };
// TESTS_NUMBERS = new int[] { 43 };
}
public FlowAnalysisTest(String name) {
super(name);
}
public static Test suite() {
return buildAllCompliancesTestSuite(testClass());
}
public void test001() {
this.runNegativeTest(new String[] {
"X.java", // =================
"public class X {\n" +
" public String foo(int i) {\n" +
" if (true) {\n" +
" return null;\n" +
" }\n" +
" if (i > 0) {\n" +
" return null;\n" +
" }\n" +
" } \n" +
"}\n",
},
"----------\n" +
"1. ERROR in X.java (at line 2)\n" +
" public String foo(int i) {\n" +
" ^^^^^^^^^^\n" +
"This method must return a result of type String\n" +
"----------\n" +
"2. WARNING in X.java (at line 6)\n" +
" if (i > 0) {\n" +
" return null;\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127255
// Compiler incorrectly reports "variable may not have been initialized"
public void test002() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportParameterAssignment, CompilerOptions.ERROR);
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test() {\n" +
" int c1, c2;\n" +
" while ((char) (c1 = 0) == 1) {}\n" +
" if (c1 == 0) {} // silent\n" +
" if (c2 == 0) {} // complain\n" +
" }\n" +
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" if (c2 == 0) {} // complain\n" +
" ^^\n" +
"The local variable c2 may not have been initialized\n" +
"----------\n",
null, true, options);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127255
// Compiler incorrectly reports "variable may not have been initialized"
public void test003() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportParameterAssignment, CompilerOptions.ERROR);
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test() {\n" +
" int c1, c2;\n" +
" while ((char) (c1 = 0) == 1) ;\n" +
" if (c1 == 0) {} // silent\n" +
" if (c2 == 0) {} // complain\n" +
" }\n" +
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" if (c2 == 0) {} // complain\n" +
" ^^\n" +
"The local variable c2 may not have been initialized\n" +
"----------\n",
null, true, options);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127255
// Compiler incorrectly reports "variable may not have been initialized"
public void test004() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportParameterAssignment, CompilerOptions.ERROR);
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test() {\n" +
" int c1, c2;\n" +
" for (;(char) (c1 = 0) == 1;) ;\n" +
" if (c1 == 0) {} // silent\n" +
" if (c2 == 0) {} // complain\n" +
" }\n" +
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" if (c2 == 0) {} // complain\n" +
" ^^\n" +
"The local variable c2 may not have been initialized\n" +
"----------\n",
null, true, options);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127255
// Compiler incorrectly reports "variable may not have been initialized"
public void test005() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportParameterAssignment, CompilerOptions.ERROR);
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test() {\n" +
" int c1, c2;\n" +
" do ; while ((char) (c1 = 0) == 1);\n" +
" if (c1 == 0) {} // silent\n" +
" if (c2 == 0) {} // complain\n" +
" }\n" +
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" if (c2 == 0) {} // complain\n" +
" ^^\n" +
"The local variable c2 may not have been initialized\n" +
"----------\n",
null, true, options);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// basic scenario
public void test006() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" case 1:\n" +
" System.out.println(1); // complain: possible fall-through\n" +
" break;\n" +
" case 2:\n" +
" System.out.println(3); // silent because of break\n" +
" return;\n" +
" case 3: // silent because of return\n" +
" case 4: // silent because grouped cases\n" +
" default:\n" +
" System.out.println(\"default\"); //$NON-NLS-1$\n" +
" }\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 6)\n" +
" case 1:\n" +
" ^^^^^^\n" +
"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// SuppressWarnings effect - explicit fallthrough token
public void test007() {
if (this.complianceLevel == ClassFileConstants.JDK1_5) {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.WARNING);
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" @SuppressWarnings(\"fallthrough\")\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" case 1:\n" +
" System.out.println(1); // silent because of SuppressWarnings\n" +
" }\n" +
" }\n" +
" void foo() {\n" +
" Zork z;\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. ERROR in X.java (at line 12)\n" +
" Zork z;\n" +
" ^^^^\n" +
"Zork cannot be resolved to a type\n" +
"----------\n",
null, true, options);
}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// deep return (1) - fake reachable is seen as reachable
public void test008() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0);\n" +
" if (true) {\n" +
" return;\n" +
" }\n" +
" case 1:\n" +
" System.out.println(1);\n" +
" }\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 9)\n" +
" case 1:\n" +
" ^^^^^^\n" +
"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// deep return (2)
public void test009() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test(int p, boolean b) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0);\n" +
" if (b) {\n" +
" return;\n" +
" }\n" +
" else {\n" +
" return;\n" +
" }\n" +
" case 1:\n" +
" System.out.println(1);\n" +
" }\n" +
" }\n" +
"}"
},
"",
null, true, null, options, null);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// deep return (3), limit: cannot recognize that we won't return
public void test010() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public void test(int p, boolean b) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.exit(0);\n" +
" case 1:\n" + // complain
" System.out.println(1);\n" +
" }\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 6)\n" +
" case 1:\n" +
" ^^^^^^\n" +
"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// SuppressWarnings effect - implicit, using all token
public void test011() {
if (this.complianceLevel == ClassFileConstants.JDK1_5) {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.WARNING);
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" @SuppressWarnings(\"all\")\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" case 1:\n" +
" System.out.println(1); // silent because of SuppressWarnings\n" +
" }\n" +
" }\n" +
" Zork z;\n" + // complain on Zork (unknown type)
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 11)\n" +
" Zork z;\n" +
" ^^^^\n" +
"Zork cannot be resolved to a type\n" +
"----------\n",
null, true, options);
}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127730
// [compiler] skip fall-through case warning when the fall-through is documented
// skip because of comment
public void _test012() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" // on purpose fall-through\n" +
" case 1:\n" +
" System.out.println(1); // silent because of comment alone on its line above \n" +
" }\n" +
" }\n" +
"}"
},
"",
null, true, null, options, null);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127730
// [compiler] skip fall-through case warning when the fall-through is documented
// skip because of comment - default label
public void _test013() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" // on purpose fall-through\n" +
" default:\n" +
" System.out.println(1); // silent because of comment alone on its line above \n" +
" }\n" +
" }\n" +
"}"
},
"",
null, true, null, options, null);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// basic scenario: default label
public void test014() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
// note: the comment above is not alone on its line, hence it does not
// protect against fall-through diagnostic
" default:\n" +
" System.out.println(1); // complain: possible fall-through\n" +
" }\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 6)\n" +
" default:\n" +
" ^^^^^^^\n" +
"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// skip because of comment - variants
public void test015() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" // on purpose fall-through\n" +
"\n" + // extraneous line breaks fall-through protection
" case 1:\n" +
" System.out.println(1); // silent because of comment alone on its line above \n" +
" }\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 8)\n" +
" case 1:\n" +
" ^^^^^^\n" +
"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// skip because of comment - variants
public void test016() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" // on purpose fall-through\n" +
" /* other comment */\n" + // non-single line comment breaks fall-through protection
" case 1:\n" +
" System.out.println(1); // silent because of comment alone on its line above \n" +
" }\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 8)\n" +
" case 1:\n" +
" ^^^^^^\n" +
"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127730
// [compiler] skip fall-through case warning when the fall-through is documented
// skip because of comment - variants
public void _test017() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0);\n" +
"// on purpose fall-through\n" + // very beginning of line
" case 1:\n" +
" System.out.println(1); // silent because of comment alone on its line above \n" +
" }\n" +
" }\n" +
"}"
},
"",
null, true, null, options, null);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=127730
// [compiler] skip fall-through case warning when the fall-through is documented
// skip because of comment - variants
public void _test018() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0);\n" +
" //\n" + // empty line comment alone upon its line
" case 1:\n" +
" System.out.println(1); // silent because of comment alone on its line above \n" +
" }\n" +
" }\n" +
"}"
},
"",
null, true, null, options, null);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// conditioned break
public void test019() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public void test(int p, boolean b) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" if (b) {\n" +
" break;\n" +
" }\n" +
" case 1:\n" +
" System.out.println(1); // silent because of comment alone on its line above \n" +
" }\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 8)\n" +
" case 1:\n" +
" ^^^^^^\n" +
"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// default reporting is ignore
public void test020() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" public void test(int p) {\n" +
" switch (p) {\n" +
" case 0:\n" +
" System.out.println(0); // silent because first case\n" +
" case 1:\n" +
" System.out.println(1); // silent because default level is ignore\n" +
" }\n" +
" }\n" +
" Zork z;\n" + // complain on Zork (unknown type)
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 10)\n" +
" Zork z;\n" +
" ^^^^\n" +
"Zork cannot be resolved to a type\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836
// [compiler] warning on fall through
// problem category
public void test021() {
if (ProblemReporter.getProblemCategory(ProblemSeverities.Warning, IProblem.FallthroughCase) !=
CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM) {
fail("bad category for fall-through case problem");
}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=128840
public void test022() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportEmptyStatement, CompilerOptions.ERROR);
options.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.IGNORE);
runNegativeTest(
// test directory preparation
true /* flush output directory */,
new String[] { /* test files */
"X.java",
"public class X {\n" +
" public static void main(String[] args) {\n" +
" if (true)\n" +
" ;\n" +
" else\n" +
" ;\n" +
" }\n" +
"}"
},
// compiler options
null /* no class libraries */,
options /* custom options */,
"----------\n" + /* expected compiler log */
"1. ERROR in X.java (at line 4)\n" +
" ;\n" +
" ^\n" +
"Empty control-flow statement\n" +
"----------\n" +
"2. ERROR in X.java (at line 6)\n" +
" ;\n" +
" ^\n" +
"Empty control-flow statement\n" +
"----------\n",
// javac options
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */);
}
public void test023() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" public static void main(String[] args) {\n" +
" final X x;\n" +
" while (true) {\n" +
" if (true) {\n" +
" break;\n" +
" }\n" +
" x = new X();\n" +
" }\n" +
" x.foo();\n" +
" }\n" +
" public void foo() {\n" +
" }\n" +
"}"
},
"----------\n" +
"1. WARNING in X.java (at line 8)\n" +
" x = new X();\n" +
" ^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. ERROR in X.java (at line 10)\n" +
" x.foo();\n" +
" ^\n" +
"The local variable x may not have been initialized\n" +
"----------\n",
JavacTestOptions.JavacHasABug.JavacBugFixed_6_10);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=132974
public void test024() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" public void foo(boolean b) {\n" +
" final Object l;\n" +
" do {\n" +
" if (b) {\n" +
" l = new Object();\n" +
" break;\n" +
" }\n" +
" } while (false);\n" +
" l.toString();\n" +
" }\n" +
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 10)\n" +
" l.toString();\n" +
" ^\n" +
"The local variable l may not have been initialized\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=135602
public void test025() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public static void main(String[] args) {\n" +
" System.out.print(\"[starting]\");\n" +
" X l = new X();\n" +
" l.testLoop();\n" +
" System.out.println(\"[finished]\");\n" +
" }\n" +
"\n" +
" public void testLoop() {\n" +
" int loops = 0;\n" +
"\n" +
" do {\n" +
" System.out.print(\"[Loop \" + loops + \"]\");\n" +
" if (loops > 2) {\n" +
" return;\n" +
" }\n" +
"\n" +
" if (loops < 4) {\n" +
" ++loops;\n" +
" continue; \n" +
" }\n" +
" } while (false);\n" +
" }\n" +
"\n" +
"}\n"
},
"[starting][Loop 0][finished]");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=137298
public void test026() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo(Object o1) {\n" +
" int a00, a01, a02, a03, a04, a05, a06, a07, a08, a09;\n" +
" int a10, a11, a12, a13, a14, a15, a16, a17, a18, a19;\n" +
" int a20, a21, a22, a23, a24, a25, a26, a27, a28, a29;\n" +
" int a30, a31, a32, a33, a34, a35, a36, a37, a38, a39;\n" +
" int a40, a41, a42, a43, a44, a45, a46, a47, a48, a49;\n" +
" int a50, a51, a52, a53, a54, a55, a56, a57, a58, a59;\n" +
" int a60, a61, a62, a63, a64, a65, a66, a67, a68, a69;\n" +
" String s;\n" +
" Object o2 = o1;\n" +
" if (o2 == null) {\n" +
" s = \"\";\n" +
" }\n" +
" System.out.println(s);\n" +
" }\n" +
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 15)\n" +
" System.out.println(s);\n" +
" ^\n" +
"The local variable s may not have been initialized\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Non-recursive approach for deep binary expressions. Check that the
// flow analysis doesn't break.
public void test027() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public static void main(String args[]) {\n" +
" String s;\n" +
" if (args.length == 0) {\n" +
" s = \"s\";\n" +
" } else {\n" +
" s = args[0];\n" +
" }\n" +
" System.out.println(s + \"-\" + s + \"-\" + s + \"-\" +\n" +
" s + \"-\" + s + \"-\" + s + \"-\" +\n" +
" s + \"-\" + s + \"-\" + s + \"-\" +\n" +
" s + \"-\" + s + \"-\" + s + \"-\" +\n" +
" s + \"-\" + s + \"-\" + s + \"-\");\n" +
" }\n" +
"}"
},
"s-s-s-s-s-s-s-s-s-s-s-s-s-s-s-");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=155423
public void test028() throws Exception {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" {\n" +
" if (true) throw new NullPointerException();\n" +
" }\n" +
"}\n" // =================
},
"");
// check no default return opcode is appended
String expectedOutput =
" public X();\n" +
" 0 aload_0 [this]\n" +
" 1 invokespecial java.lang.Object() [8]\n" +
" 4 new java.lang.NullPointerException [10]\n" +
" 7 dup\n" +
" 8 invokespecial java.lang.NullPointerException() [12]\n" +
" 11 athrow\n" +
" Line numbers:\n" +
" [pc: 0, line: 1]\n" +
" [pc: 4, line: 3]\n" +
" Local variable table:\n" +
" [pc: 0, pc: 12] local: this index: 0 type: X\n";
File f = new File(OUTPUT_DIR + File.separator + "X.class");
byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
int index = result.indexOf(expectedOutput);
if (index == -1 || expectedOutput.length() == 0) {
System.out.println(Util.displayString(result, 3));
}
if (index == -1) {
assertEquals("Wrong contents", expectedOutput, result);
}
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=155423 - variation
public void test029() throws Exception {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" {\n" +
" if (true) throw new NullPointerException();\n" +
" }\n" +
" X() {\n" +
" System.out.println();\n" +
" }\n" +
"}\n", // =================
},
"");
// check no default return opcode is appended
String expectedOutput =
" // Method descriptor #6 ()V\n" +
" // Stack: 2, Locals: 1\n" +
" X();\n" +
" 0 aload_0 [this]\n" +
" 1 invokespecial java.lang.Object() [8]\n" +
" 4 new java.lang.NullPointerException [10]\n" +
" 7 dup\n" +
" 8 invokespecial java.lang.NullPointerException() [12]\n" +
" 11 athrow\n" +
" Line numbers:\n" +
" [pc: 0, line: 5]\n" +
" [pc: 4, line: 3]\n" +
" Local variable table:\n" +
" [pc: 0, pc: 12] local: this index: 0 type: X\n";
File f = new File(OUTPUT_DIR + File.separator + "X.class");
byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
int index = result.indexOf(expectedOutput);
if (index == -1 || expectedOutput.length() == 0) {
System.out.println(Util.displayString(result, 3));
}
if (index == -1) {
assertEquals("Wrong contents", expectedOutput, result);
}
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=155423 - variation
public void test030() throws Exception {
this.runConformTest(
new String[] {
"X.java",
"class Y {\n" +
" Y(Object o) {\n" +
" System.out.print(o);\n" +
" }\n" +
"}\n" +
"\n" +
"public class X extends Y {\n" +
" {\n" +
" if (true)\n" +
" throw new NullPointerException();\n" +
" }\n" +
"\n" +
" X() {\n" +
" super(new Object() {\n" +
" public String toString() {\n" +
" return \"SUCCESS:\";\n" +
" }\n" +
" });\n" +
" System.out.println();\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" new X();\n" +
" } catch(NullPointerException e) {\n" +
" System.out.println(\"caught:NPE\");\n" +
" }\n" +
" }\n" +
"}\n", // =================
},
"SUCCESS:caught:NPE");
// check no default return opcode is appended
String expectedOutput =
" // Method descriptor #6 ()V\n" +
" // Stack: 3, Locals: 1\n" +
" X();\n" +
" 0 aload_0 [this]\n" +
" 1 new X$1 [8]\n" +
" 4 dup\n" +
" 5 invokespecial X$1() [10]\n" +
" 8 invokespecial Y(java.lang.Object) [12]\n" +
" 11 new java.lang.NullPointerException [15]\n" +
" 14 dup\n" +
" 15 invokespecial java.lang.NullPointerException() [17]\n" +
" 18 athrow\n" +
" Line numbers:\n" +
" [pc: 0, line: 14]\n" +
" [pc: 11, line: 10]\n" +
" Local variable table:\n" +
" [pc: 0, pc: 19] local: this index: 0 type: X\n";
File f = new File(OUTPUT_DIR + File.separator + "X.class");
byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
int index = result.indexOf(expectedOutput);
if (index == -1 || expectedOutput.length() == 0) {
System.out.println(Util.displayString(result, 3));
}
if (index == -1) {
assertEquals("Wrong contents", expectedOutput, result);
}
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=155423 - variation
public void test031() {
this.runConformTest(
new String[] {
"X.java",
"class Y {\n" +
" Y(Object o) {\n" +
" }\n" +
"}\n" +
"\n" +
"public class X extends Y {\n" +
" final int blank;\n" +
" {\n" +
" if (true)\n" +
" throw new NullPointerException();\n" +
" }\n" +
"\n" +
" X() {\n" +
" super(new Object() {});\n" +
" }\n" +
"}\n", // =================
},
"");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=155423 - variation
public void test032() {
this.runNegativeTest(
new String[] {
"X.java",
"class Y {\n" +
" Y(int i) {\n" +
" }\n" +
"}\n" +
"\n" +
"public class X extends Y {\n" +
" final int blank;\n" +
" {\n" +
" if (true)\n" +
" throw new NullPointerException();\n" +
" }\n" +
"\n" +
" X() {\n" +
" super(blank = 0);\n" +
" }\n" +
"}\n", // =================
},
"----------\n" +
"1. ERROR in X.java (at line 14)\n" +
" super(blank = 0);\n" +
" ^^^^^\n" +
"Cannot refer to an instance field blank while explicitly invoking a constructor\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=155423 - variation
public void test033() {
this.runConformTest(
new String[] {
"X.java",
"class Y {\n" +
" Y(int i) {\n" +
" }\n" +
"}\n" +
"public class X extends Y {\n" +
" final int blank;\n" +
" {\n" +
" if (true)\n" +
" throw new NullPointerException();\n" +
" }\n" +
" X() {\n" +
" super(0);\n" +
" blank = 0;\n" +
" }\n" +
"}\n", // =================
},
"");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162918
public void test034() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo1() {\n" +
" switch (1) {\n" +
" case 0:\n" +
" final int i = 1;\n" +
" case i: // should complain: i not initialized\n" +
" System.out.println(i); // should complain: i not initialized\n" +
" }\n" +
" }\n" +
"}"
},
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" case i: // should complain: i not initialized\n" +
" ^\n" +
"The local variable i may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 7)\n" +
" System.out.println(i); // should complain: i not initialized\n" +
" ^\n" +
"The local variable i may not have been initialized\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162918
// variant
public void test035() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo2() {\n" +
" switch (1) {\n" +
" case 0:\n" +
" int j = 0;\n" +
" case 1:\n" +
" System.out.println(j); // should complain: j not initialized\n" +
" }\n" +
" }\n" +
"}",
},
"----------\n" +
"1. ERROR in X.java (at line 7)\n" +
" System.out.println(j); // should complain: j not initialized\n" +
" ^\n" +
"The local variable j may not have been initialized\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162918
// variant - not a flow analysis issue per se, contrast with 34 and 35 above
public void test036() {
String src =
"public class X {\n" +
" void foo3() {\n" +
" switch (1) {\n" +
" case 0:\n" +
" class Local {\n" +
" }\n" +
" ;\n" +
" case 1:\n" +
" new Local();\n" + // complain for compliance >= 1.4
" }\n" +
" }\n" +
"}";
if (this.complianceLevel <= ClassFileConstants.JDK1_3) {
this.runConformTest(
new String[] {
"X.java",
src
},
""
);
} else {
this.runNegativeTest(
new String[] {
"X.java",
src
},
"----------\n" +
"1. ERROR in X.java (at line 9)\n" +
" new Local();\n" +
" ^^^^^\n" +
"Local cannot be resolved to a type\n" +
"----------\n");
}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
public void test037() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo() {\n" +
" if (false) {\n" +
" String s;\n" +
" System.out.println(s);\n" +
" }\n" +
" }\n" +
"}"
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" if (false) {\n" +
" String s;\n" +
" System.out.println(s);\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. ERROR in X.java (at line 5)\n" +
" System.out.println(s);\n" +
" ^\n" +
"The local variable s may not have been initialized\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
// variant: the declaration is outside of the fake reachable block
public void test038() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s;\n" +
" if (false) {\n" +
" System.out.println(s);\n" +
" }\n" +
" }\n" +
"}"
},
"");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
// variant with deeper nesting
public void test039() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo() {\n" +
" if (false) {\n" +
" String s;\n" +
" if (System.out != null) {\n" +
" System.out.println(s);\n" +
" }\n" +
" }\n" +
" }\n" +
"}"
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" if (false) {\n" +
" String s;\n" +
" if (System.out != null) {\n" +
" System.out.println(s);\n" +
" }\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. ERROR in X.java (at line 6)\n" +
" System.out.println(s);\n" +
" ^\n" +
"The local variable s may not have been initialized\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
// variant - checking duplicate initialization of final variables
public void test040() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo() {\n" +
" final String s = \"\";\n" +
" if (false) {\n" +
" s = \"\";\n" +
" }\n" +
" }\n" +
"}"
},
"----------\n" +
"1. WARNING in X.java (at line 4)\n" +
" if (false) {\n" +
" s = \"\";\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. ERROR in X.java (at line 5)\n" +
" s = \"\";\n" +
" ^\n" +
"The final local variable s cannot be assigned. It must be blank and not using a compound assignment\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
// variant - checking duplicate initialization of final variables
public void test041() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo() {\n" +
" final String s;\n" +
" s = \"\";\n" +
" if (false) {\n" +
" s = \"\";\n" +
" }\n" +
" }\n" +
"}"
},
"");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
// variant - checking duplicate initialization of final variables
public void test042() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo() {\n" +
" final String s;\n" +
" if (false) {\n" +
" s = \"\";\n" +
" }\n" +
" s = \"\";\n" +
" }\n" +
"}"
},
"----------\n" +
"1. WARNING in X.java (at line 4)\n" +
" if (false) {\n" +
" s = \"\";\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. ERROR in X.java (at line 7)\n" +
" s = \"\";\n" +
" ^\n" +
"The final local variable s may already have been assigned\n" +
"----------\n");
}
// switch and definite assignment
public void test043() {
this.runConformTest(
new String[] {
"X.java",
"public abstract class X {\n" +
" public static void main(String[] args) {\n" +
" for (int i = 0; i < 3; i++) {\n" +
" System.out.print(i);\n" +
" switch (i) {\n" +
" case 1:\n" +
" final int j;\n" +
" j = 1;\n" +
" System.out.println(j);\n" +
" break;\n" +
" case 2:\n" +
" j = 2;\n" +
" System.out.println(j);\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n",
},
"011\n22");
}
// switch and definite assignment
public void test044() {
this.runNegativeTest(
new String[] {
"X.java",
"public abstract class X {\n" +
" public static void main(String[] args) {\n" +
" for (int i = 0; i < 3; i++) {\n" +
" System.out.print(i);\n" +
" switch (i) {\n" +
" case 1:\n" +
" final int j = 1;\n" +
" System.out.println(j);\n" +
" break;\n" +
" case 2:\n" +
" j = 2;\n" +
" System.out.println(j);\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n",
},
"----------\n" +
"1. ERROR in X.java (at line 11)\n" +
" j = 2;\n" +
" ^\n" +
"The final local variable j cannot be assigned. It must be blank and not using a compound assignment\n" +
"----------\n");
}
// switch and definite assignment
// **
public void test045() {
this.runNegativeTest(
new String[] {
"X.java",
"public abstract class X {\n" +
" public static void main(String[] args) {\n" +
" switch (args.length) {\n" +
" case 1:\n" +
" final int j = 1;\n" +
" case 2:\n" +
" switch (5) {\n" +
" case j:\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n",
},
"----------\n" +
"1. ERROR in X.java (at line 8)\n" +
" case j:\n" +
" ^\n" +
"The local variable j may not have been initialized\n" +
"----------\n");
}
// for and definite assignment
public void test046() {
this.runConformTest(
true,
new String[] {
"X.java",
"public abstract class X {\n" +
" public static void main(String args[]) {\n" +
" for (final int i; 0 < (i = 1); i = i + 1) {\n" +
" System.out.println(i);\n" +
" break;\n" +
" }\n" +
" }\n" +
"}\n",
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" for (final int i; 0 < (i = 1); i = i + 1) {\n" +
" ^^^^^^^^^\n" +
"Dead code\n" +
"----------\n",
"1",
"",
JavacTestOptions.JavacHasABug.JavacBug4660984);
}
// do while and named labels
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=176472
// variant
public void test047() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public void foo() {\n" +
" done: do\n" +
" break done;\n" +
" while (false);\n" +
" System.out.println();\n" +
" }\n" +
"}\n",
},
"");
}
// labeled loop
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=200158
// contrast this with test049
public void test048() {
runTest(
new String[] {
"X.java",
"public class X {\n" +
" private static final boolean b = false;\n" +
" public Object foo() {\n" +
" if (b) {\n" +
" label: while (bar()) {\n" +
" }\n" +
" return null;\n" +
" }\n" +
" return null;\n" +
" }\n" +
" boolean bar() {\n" +
" return false;\n" +
" }\n" +
"}\n"
},
false /* expectingCompilerErrors */,
"----------\n" +
"1. WARNING in X.java (at line 5)\n" +
" label: while (bar()) {\n" +
" ^^^^^\n" +
"The label label is never explicitly referenced\n" +
"----------\n" /* expectedCompilerLog */,
"" /* expectedOutputString */,
"" /* expectedErrorString */,
false /* forceExecution */,
null /* classLib */,
true /* shouldFlushOutputDirectory */,
null /* vmArguments */,
null /* customOptions */,
null /* clientRequestor */,
true /* skipJavac */);
}
// labeled loop
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=200158
// variant: this one passes
public void test049() {
runTest(
new String[] {
"X.java",
"public class X {\n" +
" private static final boolean b = false;\n" +
" public Object foo() {\n" +
" if (b) {\n" +
" while (bar()) {\n" +
" }\n" +
" return null;\n" +
" }\n" +
" return null;\n" +
" }\n" +
" boolean bar() {\n" +
" return false;\n" +
" }\n" +
"}\n"
},
false /* expectingCompilerErrors */,
"" /* expectedCompilerLog */,
"" /* expectedOutputString */,
"" /* expectedErrorString */,
false /* forceExecution */,
null /* classLib */,
true /* shouldFlushOutputDirectory */,
null /* vmArguments */,
null /* customOptions */,
null /* clientRequestor */,
true /* skipJavac */);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=235781
public void test050_definite_assigment_and_if_true() {
runConformTest(
// test directory preparation
new String[] { /* test files */
"X.java",
"public class X {\n" +
" final int i;\n" +
" X() {\n" +
" if (true) {\n" +
" throw new NullPointerException();\n" +
" }\n" +
" }\n" +
"}\n"
});
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=235781
// variant
public void test051_definite_assigment_and_if_true() {
runConformTest(
// test directory preparation
new String[] { /* test files */
"X.java",
"public class X {\n" +
" X() {\n" +
" final int i;\n" +
" if (true) {\n" +
" throw new NullPointerException();\n" +
" }\n" +
" System.out.println(i);\n" +
" }\n" +
"}\n"
}
);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399
public void test052() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void foo(boolean b) {\n" +
" if (b && false) {\n" +
" int i = 0; // deadcode\n" +
" return; // 1\n" +
" }\n" +
" return;\n" +
" return;\n" +
" }\n" +
"} \n"
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" if (b && false) {\n" +
" int i = 0; // deadcode\n" +
" return; // 1\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. ERROR in X.java (at line 8)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399 - variation
public void test053() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void foo(boolean b) {\n" +
" if (false && b) {\n" +
" int j = 0; // deadcode\n" +
" return; // 2\n" +
" }\n" +
" return;\n" +
" return;\n" +
" }\n" +
"} \n"
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" if (false && b) {\n" +
" ^\n" +
"Dead code\n" +
"----------\n" +
"2. WARNING in X.java (at line 3)\n" +
" if (false && b) {\n" +
" int j = 0; // deadcode\n" +
" return; // 2\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"3. ERROR in X.java (at line 8)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399 - variation
public void test054() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void foo(boolean b) {\n" +
" while (true) {\n" +
" if (true) break;\n" +
" int k = 0; // deadcode\n" +
" }\n" +
" return;\n" +
" return;\n" +
" }\n" +
"} \n"
},
"----------\n" +
"1. WARNING in X.java (at line 5)\n" +
" int k = 0; // deadcode\n" +
" ^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. ERROR in X.java (at line 8)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399 - variation
public void test055() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void foo(boolean b) {\n" +
" if (true || b) {\n" +
" int l = 0; // deadcode\n" +
" return; // 2a\n" +
" } \n" +
" return;\n" +
" return;\n" +
" }\n" +
"} \n"
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" if (true || b) {\n" +
" ^\n" +
"Dead code\n" +
"----------\n" +
"2. WARNING in X.java (at line 7)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"3. ERROR in X.java (at line 8)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399 - variation
public void test056() {
if (this.complianceLevel < ClassFileConstants.JDK1_4) {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void bar() {\n" +
" return;\n" +
" {\n" +
" return; // 3\n" +
" }\n" +
" }\n" +
" void baz() {\n" +
" return;\n" +
" {\n" +
" }\n" +
" } \n" +
" void baz2() {\n" +
" return;\n" +
" ; // 4\n" +
" } \n" +
"} \n"
},
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" {\n" +
" return; // 3\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^\n" +
"Unreachable code\n" +
"----------\n" +
"2. ERROR in X.java (at line 10)\n" +
" {\n" +
" }\n" +
" ^^^^^\n" +
"Unreachable code\n" +
"----------\n");
return;
}
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void bar() {\n" +
" return;\n" +
" {\n" +
" return; // 3\n" +
" }\n" +
" }\n" +
" void baz() {\n" +
" return;\n" +
" {\n" +
" }\n" +
" } \n" +
" void baz2() {\n" +
" return;\n" +
" ; // 4\n" +
" } \n" +
"} \n"
},
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" {\n" +
" return; // 3\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^\n" +
"Unreachable code\n" +
"----------\n" +
"2. ERROR in X.java (at line 10)\n" +
" {\n" +
" }\n" +
" ^^^^^\n" +
"Unreachable code\n" +
"----------\n" +
"3. ERROR in X.java (at line 15)\n" +
" ; // 4\n" +
" ^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=110544
public void test057() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void foo(int x, int[] array) {\n" +
" for (int i = 0; \n" +
" i < array.length; \n" +
" i++) {//dead code\n" +
" if (x == array[i])\n" +
" return;\n" +
" else\n" +
" break;\n" +
" }\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. WARNING in X.java (at line 5)\n" +
" i++) {//dead code\n" +
" ^^^\n" +
"Dead code\n" +
"----------\n" +
"2. WARNING in X.java (at line 9)\n" +
" break;\n" +
" ^^^^^^\n" +
"Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399 - variation
public void test058() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void foo() {\n" +
" if (false) {\n" +
" class Local {\n" +
" int i = 12;\n" +
" { i++; }\n" +
" void method() {\n" +
" if (false)\n" +
" System.out.println();\n" +
" return;\n" +
" return;\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" if (false) {\n" +
" class Local {\n" +
" int i = 12;\n" +
" { i++; }\n" +
" void method() {\n" +
" if (false)\n" +
" System.out.println();\n" +
" return;\n" +
" return;\n" +
" }\n" +
" }\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"2. WARNING in X.java (at line 4)\n" +
" class Local {\n" +
" ^^^^^\n" +
"The type Local is never used locally\n" +
"----------\n" +
"3. WARNING in X.java (at line 7)\n" +
" void method() {\n" +
" ^^^^^^^^\n" +
"The method method() from the type Local is never used locally\n" +
"----------\n" +
"4. ERROR in X.java (at line 11)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399 - variation
public void test059() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" void foo(boolean b) {\n" +
" int i = false && b ? 0 : 1;\n" +
" if (false) {\n" +
" int j = false && b ? 0 : 1;\n" +
" }\n" +
" return;\n" +
" return;\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. WARNING in X.java (at line 3)\n" +
" int i = false && b ? 0 : 1;\n" +
" ^\n" +
"Dead code\n" +
"----------\n" +
"2. WARNING in X.java (at line 3)\n" +
" int i = false && b ? 0 : 1;\n" +
" ^\n" +
"Dead code\n" +
"----------\n" +
"3. WARNING in X.java (at line 4)\n" +
" if (false) {\n" +
" int j = false && b ? 0 : 1;\n" +
" }\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"4. ERROR in X.java (at line 8)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=48399 - variation
public void test060() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" static final boolean DEBUG = false;\n" +
" static final int DEBUG_LEVEL = 0;\n" +
" boolean check() { return true; }\n" +
" void foo(boolean b) {\n" +
" if (DEBUG)\n" +
" System.out.println(\"fake reachable1\"); //$NON-NLS-1$\n" +
" if (DEBUG && b)\n" +
" System.out.println(\"fake reachable2\"); //$NON-NLS-1$\n" +
" if (DEBUG && check())\n" +
" System.out.println(\"fake reachable3\"); //$NON-NLS-1$\n" +
" if (b && DEBUG)\n" +
" System.out.println(\"fake reachable4\"); //$NON-NLS-1$\n" +
" if (check() && DEBUG)\n" +
" System.out.println(\"fake reachable5\"); //$NON-NLS-1$\n" +
" if (DEBUG_LEVEL > 1) \n" +
" System.out.println(\"fake reachable6\"); //$NON-NLS-1$\n" +
" return;\n" +
" return;\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. WARNING in X.java (at line 8)\n" +
" if (DEBUG && b)\n" +
" ^\n" +
"Dead code\n" +
"----------\n" +
"2. WARNING in X.java (at line 9)\n" +
" System.out.println(\"fake reachable2\"); //$NON-NLS-1$\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"3. WARNING in X.java (at line 10)\n" +
" if (DEBUG && check())\n" +
" ^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"4. WARNING in X.java (at line 11)\n" +
" System.out.println(\"fake reachable3\"); //$NON-NLS-1$\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"5. WARNING in X.java (at line 13)\n" +
" System.out.println(\"fake reachable4\"); //$NON-NLS-1$\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"6. WARNING in X.java (at line 15)\n" +
" System.out.println(\"fake reachable5\"); //$NON-NLS-1$\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"7. WARNING in X.java (at line 17)\n" +
" System.out.println(\"fake reachable6\"); //$NON-NLS-1$\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Dead code\n" +
"----------\n" +
"8. ERROR in X.java (at line 19)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265962
public void test061() throws Exception {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" private static final boolean isIS() {\n" +
" return System.currentTimeMillis()<0 ;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" do {\n" +
" return;\n" +
" } while(isIS() && false);\n" +
" }\n" +
"}\n", // =================
},
"");
// ensure optimized boolean codegen sequence
String expectedOutput =
" public static void main(java.lang.String[] args);\n" +
" 0 return\n" +
" Line numbers:\n" +
" [pc: 0, line: 7]\n" +
" Local variable table:\n" +
" [pc: 0, pc: 1] local: args index: 0 type: java.lang.String[]\n";
File f = new File(OUTPUT_DIR + File.separator + "X.class");
byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
int index = result.indexOf(expectedOutput);
if (index == -1 || expectedOutput.length() == 0) {
System.out.println(Util.displayString(result, 3));
}
if (index == -1) {
assertEquals("Wrong contents", expectedOutput, result);
}
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265962 - variation
public void test062() {
runNegativeTest(
new String[] { /* test files */
"X.java",
"public class X {\n" +
" private static final boolean isIS() {\n" +
" return System.currentTimeMillis()<0 ;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" do {\n" +
" return;\n" +
" } while(isIS() && false);\n" +
" return;\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. ERROR in X.java (at line 9)\n" +
" return;\n" +
" ^^^^^^^\n" +
"Unreachable code\n" +
"----------\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385
public void test063() {
Map compilerOptions = getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.ERROR);
runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" boolean bar() { return false; } \n" +
" public void foo() {" +
" if (bar())\n" +
" new IllegalArgumentException(\"You must not bar!\");\n" +
" }\n" +
"}",
},
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" new IllegalArgumentException(\"You must not bar!\");\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"The allocated object is never used\n" +
"----------\n",
null /* classLibraries */,
true /* shouldFlushOutputDirectory */,
compilerOptions);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385
// non-throwable type
public void test064() {
Map compilerOptions = getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.ERROR);
runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" boolean bar() { return false; } \n" +
" public void foo() {" +
" if (bar())\n" +
" new String(\"You must not bar!\");\n" +
" }\n" +
"}",
},
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" new String(\"You must not bar!\");\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"The allocated object is never used\n" +
"----------\n",
null /* classLibraries */,
true /* shouldFlushOutputDirectory */,
compilerOptions);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385
// warning suppressed
public void test065() {
if (this.complianceLevel < ClassFileConstants.JDK1_5) return;
Map compilerOptions = getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.WARNING);
runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" boolean bar() { return false; }\n" +
" @SuppressWarnings(\"unused\")\n" +
" public void foo() {" +
" if (bar())\n" +
" new IllegalArgumentException(\"You must not bar!\");\n" +
" }\n" +
"}",
},
"" /* expectedOutputString */,
null /* classLib */,
true /* shouldFlushOutputDirectory */,
null /* vmArguments */,
compilerOptions /* customOptions */,
null /* clientRequestor */);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385
// warning ignored (default)
public void test066() {
runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" boolean bar() { return false; }\n" +
" public void foo() {" +
" if (bar())\n" +
" new IllegalArgumentException(\"You must not bar!\");\n" +
" }\n" +
"}",
},
"" /* expectedOutputString */);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385
// instance is assigned
public void test067() {
Map compilerOptions = getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.ERROR);
runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" boolean bar() { return false; }\n" +
" Throwable t;\n" +
" public void foo() {" +
" t = new IllegalArgumentException(\"You must not bar!\");\n" +
" }\n" +
"}",
},
"" /* expectedOutputString */,
null /* classLib */,
true /* shouldFlushOutputDirectory */,
null /* vmArguments */,
compilerOptions /* customOptions */,
null /* clientRequestor */);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385
// method invoked
public void test068() {
Map compilerOptions = getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.ERROR);
runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" boolean bar() { return false; }\n" +
" public void foo() {" +
" if (bar())\n" +
" new IllegalArgumentException(\"You must not bar!\").printStackTrace();\n" +
" }\n" +
"}",
},
"" /* expectedOutputString */,
null /* classLib */,
true /* shouldFlushOutputDirectory */,
null /* vmArguments */,
compilerOptions /* customOptions */,
null /* clientRequestor */);
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385
//anonymous type
public void test069() {
Map compilerOptions = getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.ERROR);
runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" boolean bar() { return false; } \n" +
" public void foo() {" +
" if (bar())\n" +
" new Object() {};\n" +
" }\n" +
"}",
},
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" new Object() {};\n" +
" ^^^^^^^^^^^^^^^\n" +
"The allocated object is never used\n" +
"----------\n",
null /* classLibraries */,
true /* shouldFlushOutputDirectory */,
compilerOptions);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=322154
public void test070() {
Map compilerOptions = getCompilerOptions();
compilerOptions.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.ERROR);
runNegativeTest(
new String[] {
"X.java",
"public final class X {\n" +
" private X (){\n" +
" boolean flagSet = true;\n" +
" Object first = true ? null : \"\"; \n" +
" Object second = flagSet || first == null ? null :\n" +
" new Object() {};\n" +
" }\n" +
"}\n",
},
"----------\n" +
"1. WARNING in X.java (at line 4)\n" +
" Object first = true ? null : \"\"; \n" +
" ^^\n" +
"Dead code\n" +
"----------\n",
null /* classLibraries */,
true /* shouldFlushOutputDirectory */,
compilerOptions);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324154
public void test071() {
runNegativeTest(
new String[] {
"X.java",
"import java.io.*;\n" +
"public class X {\n" +
" static {\n" +
" try {\n" +
" while(true) {\n" +
" if (true)\n" +
" throw new NumberFormatException();\n" +
" else\n" +
" throw new IOException();\n" +
" }\n" +
" } catch(IOException e ) {\n" +
" // empty\n" +
" } \n" +
" } \n" +
"}\n",
},
"----------\n" +
"1. WARNING in X.java (at line 9)\n" +
" throw new IOException();\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" +
"----------\n" +
"2. WARNING in X.java (at line 9)\n" +
" throw new IOException();\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"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 2)\n" +
" public final int field1;\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");
}
// Bug 349326 - [1.7] new warning for missing try-with-resources
// variant < 1.7 using Closeable: not closed
public void testCloseable1() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING);
this.runNegativeTest(
new String[] {
"X.java",
"import java.io.File;\n" +
"import java.io.FileReader;\n" +
"import java.io.IOException;\n" +
"public class X {\n" +
" void foo() throws IOException {\n" +
" File file = new File(\"somefile\");\n" +
" FileReader fileReader = new FileReader(file); // not closed\n" +
" char[] in = new char[50];\n" +
" fileReader.read(in);\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. WARNING in X.java (at line 7)\n" +
" FileReader fileReader = new FileReader(file); // not closed\n" +
" ^^^^^^^^^^\n" +
"Resource leak: 'fileReader' is never closed\n" +
"----------\n",
null, true, options);
}
// Bug 349326 - [1.7] new warning for missing try-with-resources
// variant < 1.7 using Closeable: resource is closed, cannot suggest try-with-resources < 1.7
public void testCloseable2() {
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING);
this.runConformTest(
new String[] {
"X.java",
"import java.io.File;\n" +
"import java.io.FileReader;\n" +
"import java.io.IOException;\n" +
"public class X {\n" +
" void foo() throws IOException {\n" +
" File file = new File(\"somefile\");\n" +
" FileReader fileReader = new FileReader(file); // not closed\n" +
" char[] in = new char[50];\n" +
" fileReader.read(in);\n" +
" fileReader.close();\n" +
" }\n" +
"}\n"
},
"",
null, true, null, options, null);
}
// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
// return/break/continue inside anonymous class inside try-catch inside initializer
public void testLocalClassInInitializer1() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" static {\n" +
" final int i=4;\n" +
" try {\n" +
" Runnable runner = new Runnable() {\n" +
" public void run() {\n" +
" switch (i) {" +
" case 4: break;\n" +
" }\n" +
" int j = i;\n" +
" while (j++ < 10) {\n" +
" if (j == 2) continue;\n" +
" if (j == 4) break;\n" +
" if (j == 6) return;\n" +
" }\n" +
" }\n" +
" };\n" +
" } catch (RuntimeException re) {}\n" +
" }\n" +
"}\n"
},
"");
}
// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
// break/continue illegally inside anonymous class inside loop (loop is out of scope for break/continue)
public void testLocalClassInInitializer2() {
this.runNegativeTest(
new String[] {
"X.java",
"public class X {\n" +
" void f () {\n" +
" while (true) {\n" +
" class Inner1 {\n" +
" { if (true) break; }\n" +
" }\n" +
" new Inner1();\n" +
" }\n" +
" } \n" +
" void g () {\n" +
" outer: for (int i=1;true;i++) {\n" +
" class Inner2 {\n" +
" int j = 3;\n" +
" void foo () {\n" +
" if (2 == j) continue outer;\n" +
" else continue;\n" +
" }\n" +
" }\n" +
" new Inner2().foo();\n" +
" }\n" +
" } \n" +
"}\n"
},
"----------\n" +
"1. ERROR in X.java (at line 5)\n" +
" { if (true) break; }\n" +
" ^^^^^^\n" +
"break cannot be used outside of a loop or a switch\n" +
"----------\n" +
"2. WARNING in X.java (at line 11)\n" +
" outer: for (int i=1;true;i++) {\n" +
" ^^^^^\n" +
"The label outer is never explicitly referenced\n" +
"----------\n" +
"3. ERROR in X.java (at line 15)\n" +
" if (2 == j) continue outer;\n" +
" ^^^^^^^^^^^^^^^\n" +
"The label outer is missing\n" +
"----------\n" +
"4. ERROR in X.java (at line 16)\n" +
" else continue;\n" +
" ^^^^^^^^^\n" +
"continue cannot be used outside of a loop\n" +
"----------\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=380313
// Verify that the code runs fine with all compliance levels.
public void testBug380313() {
if (this.complianceLevel < ClassFileConstants.JDK1_5)
return;
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
"public void foo() throws Exception {\n" +
" int i = 1;\n" +
" int j = 2;\n" +
" try {\n" +
" if ((bar() == 1)) {\n" +
" if ((i == 1)) {\n" +
" int n = bar();\n" +
" if (n == 35) {\n" +
" j = 2;\n" +
" } else {\n" +
" if (bar() > 0)\n" +
" return;\n" +
" }\n" +
" } else {\n" +
" throw new Exception();\n" +
" }\n" +
" } else {\n" +
" throw new Exception();\n" +
" }\n" +
" if (bar() == 0)\n" +
" return;\n" +
" } finally {\n" +
" bar();\n" +
" }\n" +
" }\n" +
"\n" +
" private int bar() {\n" +
" return 0;\n" +
" }\n" +
"\n" +
" public static void main(String[] args) {\n" +
" }\n" +
"}\n"
},
"");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=380313
// try with resources
// Verify that the code runs fine with all compliance levels.
public void testBug380313b() {
if (this.complianceLevel < ClassFileConstants.JDK1_7)
return;
this.runConformTest(
new String[] {
"X.java",
"import java.io.FileInputStream;\n" +
"import java.io.IOException;\n" +
"public class X {\n" +
"public void foo() throws Exception {\n" +
" int i = 1;\n" +
" try {\n" +
" try (FileInputStream fis = new FileInputStream(\"\")) {\n" +
" if (i == 2)" +
" return;\n" +
" }\n" +
" if (i == 35) \n" +
" return;\n" +
" } catch(IOException e) {\n" +
" bar();\n" +
" } finally {\n" +
" bar();\n" +
" }\n" +
" }\n" +
"\n" +
" private int bar() {\n" +
" return 0;\n" +
" }\n" +
"\n" +
" public static void main(String[] args) {\n" +
" }\n" +
"}\n"
},
"");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=380750
// verify that s0 is not reported as uninitialized
public void testBug380750() {
if (this.complianceLevel < ClassFileConstants.JDK1_5)
return;
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" void foo(String[] args) {\n" +
" String s0;\n" +
" for(String s : singleton(s0=\"\")) {\n" +
" System.out.println(s);\n" +
" }\n" +
" System.out.println(s0);\n" +
" }\n" +
" String[] singleton(String s) {\n" +
" return new String[] {s};\n" +
" }\n" +
"}\n"
},
"");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391517
// java.lang.VerifyError on code that runs correctly in Eclipse 3.7 and eclipse 3.6
public void testBug391517() {
this.runConformTest(
new String[] {
"X.java",
"import java.io.PrintWriter;\n" +
"\n" +
"public class X {\n" +
"\n" +
" private static final int CONSTANT = 0;\n" +
"\n" +
" public static void main(String[] args) {\n" +
" // TODO Auto-generated method stub\n" +
"\n" +
" }\n" +
"\n" +
" static void addStackTrace(String prefix) {\n" +
" if (CONSTANT == 0) {\n" +
" return;\n" +
" }\n" +
" PrintWriter pw = null;\n" +
" new Exception().printStackTrace(pw);\n" +
" if (bar() == null) {\n" +
" System.out.println();\n" +
" }\n" +
" }\n" +
"\n" +
" static Object bar() {\n" +
" return null;\n" +
" }\n" +
"}"
},
"");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=415997
// Bug 415997 - java.lang.VerifyError: Expecting a stackmap frame at branch target
public void testBug415997a() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public static void main(String[] args) {\n" +
" Object o = null;\n" +
" if (o == null)\n" +
" if (true)\n" +
" return;\n" +
" }\n" +
"}"
},
"");
}
public void testBug415997b() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public static void main(String[] args) {\n" +
" Object o = null;\n" +
" if (o == null) {}\n" +
" else\n" +
" if (true)\n" +
" return;\n" +
" }\n" +
"}"
},
"");
}
public void testBug415997c() {
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
" public static void main(String[] args) throws Exception {\n" +
" System.out.println(ParseExpr11());\n" +
" }\n" +
" static final public Object ParseExpr11() throws Exception {\n" +
" Object expr;\n" +
" Object op = null;\n" +
" expr = ParseVarExpr();\n" +
" if (op == null) {\n" +
" if (true)\n" +
" return expr;\n" +
" }\n" +
" {\n" +
" throw new Exception(\"++/-- not supported in TUD Bantam Java.\");\n" +
" }\n" +
" }\n" +
" private static Object ParseVarExpr() {\n" +
" // TODO Auto-generated method stub\n" +
" return \"test\";\n" +
" }\n" +
"}"
},
"test");
}
public void testBug499809() {
this.runConformTest(
new String[] {
"Foo.java",
"public class Foo {\n" +
" static void foo( ) {\n" +
" String _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, a, b,\n" +
" c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, s0, s1, s2, s3, s4, s5, s6, s7;\n" +
" Object ob = new Object();\n" +
" int int1 = 0, int2 = 2, int3, int4;\n" +
" if (ob != null) {\n" +
" int4 = 1;\n" +
" }\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(\"Done\");\n" +
" }\n" +
"}\n"
},
"Done");
}
public void testBug499809a() {
this.runConformTest(
new String[] {
"Foo.java",
"public class Foo {\n" +
" static void foo( ) {\n" +
" String _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, a, b,\n" +
" c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, s0, s1, s2, s3, s4, s5, s6, s7;\n" +
" Object ob = new Object();\n" +
" int int1 = 0, int2 = 2, int3, int4;\n" +
" if (ob == null) {\n" +
" int1 = 1;\n" +
" } else {\n" +
" int4 = 1;\n" +
" }\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(\"Done\");\n" +
" }\n" +
"}\n"
},
"Done");
}
//Bug 506315 - ASTParser.createASTs() in StackMapFrame.addStackItem throws IllegalArgumentException
public void testBug506315() {
if (this.complianceLevel < ClassFileConstants.JDK1_5)
return;
this.runNegativeTest(
new String[] {
"Test.java",
"import java.util.function.Consumer;\n" +
"public class Test {\n" +
" public void test(String method) {\n" +
" String str;\n" +
" if (!method.equals(\"\")) {\n" +
" str = \"String\";\n" +
" str.concat(method);\n" +
" }\n" +
" new Consumer<String>() {\n" +
" public void accept(String s) {\n" +
" str = \"String\";\n" +
" }\n" +
" };\n" +
" }\n" +
"}\n"
},
this.complianceLevel < ClassFileConstants.JDK1_8 ?
"----------\n" +
"1. ERROR in Test.java (at line 11)\n" +
" str = \"String\";\n" +
" ^^^\n" +
"Cannot refer to the non-final local variable str defined in an enclosing scope\n" +
"----------\n"
:
"----------\n" +
"1. ERROR in Test.java (at line 11)\n" +
" str = \"String\";\n" +
" ^^^\n" +
"Local variable str defined in an enclosing scope must be final or effectively final\n" +
"----------\n");
}
public void _testBug533435() {
this.runConformTest(
new String[] {
"X.java",
"public interface X {}\n"
}, new ASTVisitor() {
public boolean visit(TypeDeclaration typeDeclaration,
CompilationUnitScope scope) {
if (new String(typeDeclaration.name).equals("X")) {
typeDeclaration.methods =
new AbstractMethodDeclaration[0];
typeDeclaration.fields = new FieldDeclaration[0];
scope.referenceContext.analyseCode();
//should not fail
}
return true;
}
});
}
public void testBug537804_comment0() {
if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses an annotation
runConformTest(
new String[] {
"Test.java",
"public class Test\n" +
"{\n" +
" private boolean dummy;\n" +
"\n" +
"//Test\n" +
" void testMethod()\n" +
" {\n" +
" @SuppressWarnings(\"unused\")\n" +
" boolean action;\n" +
"\n" +
" OUTER:\n" +
" {\n" +
" while (true)\n" +
" {\n" +
" if (dummy)\n" +
" break OUTER;\n" +
"\n" +
" action = true;\n" +
" break;\n" +
" }\n" +
"\n" +
" return;\n" +
" }\n" +
"\n" +
" return;\n" +
" }\n" +
"\n" +
"//Main Method\n" +
" public static void main(String[] arguments)\n" +
" {\n" +
" //No operation\n" +
" }\n" +
"}\n"
});
}
public void testBug537804_comment5() {
runNegativeTest(
new String[] {
"Test.java",
"public class Test\n" +
"{\n" +
" private boolean dummy;\n" +
"\n" +
"//Test\n" +
" void testMethod()\n" +
" {\n" +
" boolean action;\n" +
"\n" +
" OUTER:\n" +
" {\n" +
" while (true)\n" +
" {\n" +
" if (dummy)\n" +
" break OUTER;\n" +
"\n" +
" action = true;\n" +
" break;\n" +
" }\n" +
"\n" +
" if (action) //Okay.\n" +
" noOp();\n" +
"\n" +
" return;\n" +
" }\n" +
"\n" +
" if (action) //Missing error: 'action' may not be initialized!\n" +
" noOp();\n" +
"\n" +
" return;\n" +
" }\n" +
" void noOp()\n" +
" {\n" +
" //No operation\n" +
" }\n" +
"\n" +
"//Main Method\n" +
" public static void main(String[] arguments)\n" +
" {\n" +
" //No operation\n" +
" }\n" +
"}\n"
},
"----------\n" +
"1. ERROR in Test.java (at line 27)\n" +
" if (action) //Missing error: \'action\' may not be initialized!\n" +
" ^^^^^^\n" +
"The local variable action may not have been initialized\n" +
"----------\n");
}
public void testBug548318_001() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 11)\n" +
" yield k;\n" +
" ^\n" +
"The local variable k may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 14)\n" +
" return k + it;\n" +
" ^\n" +
"The local variable k may not have been initialized\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" final int k;\n" +
"\n" +
" int it = switch (i) { \n" +
" case 1 -> {\n" +
" k = 1;\n" +
" yield k ;\n" +
" }\n" +
" default -> {\n" +
" yield k;\n" +
" }\n" +
" };\n" +
" return k + it;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
public void testBug548318_002() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 5)\n" +
" k = switch (i) { \n" +
" ^\n" +
"The final local variable k may already have been assigned\n" +
"----------\n" +
"2. ERROR in X.java (at line 11)\n" +
" yield k;\n" +
" ^\n" +
"The local variable k may not have been initialized\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" final int k;\n" +
"\n" +
" k = switch (i) { \n" +
" case 1 -> {\n" +
" k = 1;\n" +
" yield k ;\n" +
" }\n" +
" default -> {\n" +
" yield k;\n" +
" }\n" +
" };\n" +
" return k;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/*
* k is definitely assigned - no errors on that front.
*/
public void testBug548318_003() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 23)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" final int k;\n" +
"\n" +
" int it = switch (i) { \n" +
" case 1 -> {\n" +
" k = 1;\n" +
" yield k ;\n" +
" }\n" +
" case 2 -> {\n" +
" k = 2;\n" +
" yield k ;\n" +
" }\n" +
" default -> {\n" +
" k = 3;\n" +
" yield k;\n" +
" }\n" +
" };\n" +
" return k;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
public void testBug548318_004() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 7)\n" +
" k = 1;\n" +
" ^\n" +
"The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" +
"----------\n" +
"2. ERROR in X.java (at line 11)\n" +
" k = 2;\n" +
" ^\n" +
"The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" +
"----------\n" +
"3. ERROR in X.java (at line 15)\n" +
" k = 3;\n" +
" ^\n" +
"The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" +
"----------\n" +
"4. ERROR in X.java (at line 23)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" final int k = 1;\n" +
"\n" +
" int it = switch (i) { \n" +
" case 1 -> {\n" +
" k = 1;\n" +
" yield k ;\n" +
" }\n" +
" case 2 -> {\n" +
" k = 2;\n" +
" yield k ;\n" +
" }\n" +
" default -> {\n" +
" k = 3;\n" +
" yield k;\n" +
" }\n" +
" };\n" +
" return k;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
public void testBug548318_005() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 11)\n" +
" yield k ;\n" +
" ^\n" +
"The local variable k may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 18)\n" +
" return k;\n" +
" ^\n" +
"The local variable k may not have been initialized\n" +
"----------\n" +
"3. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" final int k;\n" +
"\n" +
" int it = switch (i) { \n" +
" case 1 -> {\n" +
" k = 1;\n" +
" yield k ;\n" +
" }\n" +
" case 2 -> {\n" +
" yield k ;\n" +
" }\n" +
" default -> {\n" +
" k = 3;\n" +
" yield k;\n" +
" }\n" +
" };\n" +
" return k;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is definitely assigned after a switch expression when true iff for every value yield statement with
* expression e in the switch block that may exit the switch expression, V is definitely assigned after e when true.
* V is definitely assigned after a switch expression when false iff for every value yield statement with
* expression e in the switch block that may exit the switch expression, V is definitely assigned after e when false.
*/
public void testBug548318_006() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (i) {\n" +
" case 1 :\n" +
" v = 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" v = 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is definitely unassigned after a switch expression when true iff for every value yield statement with expression
* e in the switch block that may exit the switch expression, V is definitely unassigned before the value yield
* statement and V is definitely unassigned after e when true.
* V is definitely unassigned after a switch expression when false iff for every value yield statement with expression
* e in the switch block that may exit the switch expression, V is definitely unassigned before the value yield
* statement and V is definitely unassigned after e when false.
*/
public void testBug548318_007() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 18)\n" +
" return v + d;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (i) {\n" +
" case 1 :\n" +
" //v = 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" //v = 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" //v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
*/
public void testBug548318_008() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v = 1;\n" +
" boolean b = switch (i) {\n" +
" case 1 :\n" +
" //v = 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" //v = 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" //v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
*/
public void testBug548318_009() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" boolean b = switch (v) {\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (v) {\n" +
" case 1 :\n" +
" v = 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" v = 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before the first statement of the first switch labeled statement group in the switch block
* iff V is [un]assigned after the selector expression.
*/
public void testBug548318_010() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (i + (v =1)) {\n" +
" case 1 :\n" +
" v += 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" v = 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before the first statement of the first switch labeled statement group in the switch block
* iff V is [un]assigned after the selector expression.
*/
public void testBug548318_011() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" v += 1;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (i) {\n" +
" case 1 :\n" +
" v += 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" v = 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before the first statement of any switch labeled statement group other than the first iff
* V is [un]assigned after the selector expression and V is [un]assigned after the preceding statement.
* and V is [un]assigned after the preceding statement
*/
public void testBug548318_012() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (i + (v =1)) {\n" +
" case 1 :\n" +
" v = 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" v += 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before the first statement of any switch labeled statement group other than the first iff
* V is [un]assigned after the selector expression and V is [un]assigned after the preceding statement.
* and V is [un]assigned after the preceding statement"
*/
public void testBug548318_012b() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 15)\n" +
" return v + d;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 19)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (i) {\n" +
" case 1 :i =1;\n" +
" case 2 : {\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before the first statement of any switch labeled statement group other than the first iff
* V is [un]assigned after the selector expression and V is [un]assigned after the preceding statement.
* and V is [un]assigned after the preceding statement" needs to be checked
*/
public void testBug548318_013() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 9)\n" +
" v += 2;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 22)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" boolean b = switch (i) {\n" +
" case 1 :\n" +
" v = 1;\n" +
" yield true;\n" +
" case 2 : {\n" +
" v += 2;\n" +
" yield true;\n" +
" }\n" +
" default : {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
"\n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
* V is definitely assigned after a switch expression when true iff for every switch labeled rule one of the following is true:
* It is a switch labeled expression e and V is definitely assigned after e when true.
* It is a switch labeled block b and for every value yield statement expression e contained in b that may exit the switch expression,
* V is definitely assigned after e when true.
* It is a switch labeled throw statement.
*
* V is definitely assigned after a switch expression when false iff for every switch labeled rule one of the following is true:
* It is a switch labeled expression e and V is definitely assigned after e when false.
* It is a switch labeled block b and for every value yield statement expression e contained in b that may exit the switch expression,
* V is definitely assigned after e when false.
* It is a switch labeled throw statement.
*/
public void testBug548318_014() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 23)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v;\n" +
" boolean b = switch (i ) {\n" +
" case 0 -> (v = 1) != 0;\n" +
" case 1 -> (v = 1) == 0;\n" +
" case 2 -> {\n" +
" v = 2;\n" +
" yield true;\n" +
" }\n" +
" case 3 -> {\n" +
" v = 3;\n" +
" yield false;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
* V is definitely unassigned after a switch expression when true iff for every switch labeled rule one of the following is true:
* It is a switch labeled expression e and V is definitely unassigned after e when true .
* It is a switch labeled block b and for every value yield statement expression e contained in b that
* may exit the switch expression, V is definitely unassigned before the value yield statement and
* V is definitely unassigned after e when true.
* It is a switch labeled throw statement.
*
* V is definitely unassigned after a switch expression when false iff for every switch labeled rule one of the following is true:
* It is a switch labeled expression e and V is definitely unassigned after e when false.
* It is a switch labeled block b and for every value yield statement expression e contained in b that may
* exit the switch expression, V is definitely unassigned before the value yield statement and V is definitely unassigned
* after e when false.
* It is a switch labeled throw statement.
*/
public void testBug548318_015() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 17)\n" +
" return v + d;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 21)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v;\n" +
" boolean b = switch (i ) {\n" +
" case 0 -> true;\n" +
" case 1 -> false;\n" +
" case 2 -> {\n" +
" yield true;\n" +
" }\n" +
" case 3 -> {\n" +
" yield false;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* V is [un]assigned before any switch labeled expression or statement in the switch
* block iff V is [un]assigned after the selector expression.
*/
public void testBug548318_016() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 14)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v;\n" +
" boolean b = switch ((v = 1)) {\n" +
" case 0 -> v != 0;\n" +
" default -> throw new IOException();\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
* which are boolean-valued.
* The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
* V is [un]assigned before any switch labeled expression or statement in the switch
* block iff V is [un]assigned after the selector expression.
*/
public void testBug548318_017() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" case 0 -> v != 0;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 10)\n" +
" return v + d;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"3. ERROR in X.java (at line 14)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v;\n" +
" boolean b = switch (i) {\n" +
" case 0 -> v != 0;\n" +
" default -> throw new IOException();\n" +
" };\n" +
" int d = b == true ? 0 : 1; \n" +
" return v + d;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, V is [un]assigned after a switch expression (15.28) iff all of the following are true:
* V is [un]assigned before every yield statement that may exit the switch statement.
* For each switch labeled rule (14.11.1) in the switch block, V is [un]assigned after the
* expression, block, or throw statement of the switch labeled rule.
*/
public void testBug548318_018() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 20)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" int t = switch (i) {\n" +
" case 0 : {\n" +
" v = 1; // definitely assigned before yield\n" +
" yield v;\n" +
" }\n" +
" case 2 : {\n" +
" yield v =1; // definitely assigned after e\n" +
" }\n" +
" default : {\n" +
" yield v = 2;\n" +
" }\n" +
" };\n" +
" return v + t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, V is [un]assigned after a switch expression (15.28) iff all of the following are true:
* V is [un]assigned before every yield statement that may exit the switch statement.
* For each switch labeled rule (14.11.1) in the switch block, V is [un]assigned after the
* expression, block, or throw statement of the switch labeled rule.
*/
public void testBug548318_019() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 15)\n" +
" return v + t;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 19)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" int t = switch (i) {\n" +
" case 0 : {\n" +
" yield 1;\n" +
" }\n" +
" case 2 : {\n" +
" yield 2;\n" +
" }\n" +
" default : {\n" +
" yield 3;\n" +
" }\n" +
" };\n" +
" return v + t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
* which are boolean-valued.
* V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
*/
public void testBug548318_020() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 19)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v =1;\n" +
" int t = switch (v) {\n" +
" case 0 : {\n" +
" yield 1;\n" +
" }\n" +
" case 2 : {\n" +
" yield 2;\n" +
" }\n" +
" default : {\n" +
" yield 3;\n" +
" }\n" +
" };\n" +
" return t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
* which are boolean-valued.
* V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
*/
public void testBug548318_021() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 4)\n" +
" int t = switch (v) {\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 19)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" int t = switch (v) {\n" +
" case 0 : {\n" +
" yield 1;\n" +
" }\n" +
" case 2 : {\n" +
" yield 2;\n" +
" }\n" +
" default : {\n" +
" yield 3;\n" +
" }\n" +
" };\n" +
" return t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
* which are boolean-valued.
* V is [un]assigned before the first block statement of a switch labeled statement group (14.11.1) of a switch expression
* iff both of following are true:
* V is [un]assigned after the selector expression of the switch statement.
* If the switch labeled statement group is not the first in the switch block,
* V is [un]assigned after the last block statement of the preceding switch labeled statement group.
*/
public void testBug548318_022() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 19)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v =1;\n" +
" int t = switch (v) {\n" +
" case 0 : {\n" +
" yield v;\n" +
" }\n" +
" case 2 : {\n" +
" yield 2;\n" +
" }\n" +
" default : {\n" +
" yield 3;\n" +
" }\n" +
" };\n" +
" return t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
* which are boolean-valued.
* V is [un]assigned before the first block statement of a switch labeled statement group (14.11.1) of a switch expression
* iff both of following are true:
* V is [un]assigned after the selector expression of the switch statement.
* If the switch labeled statement group is not the first in the switch block,
* V is [un]assigned after the last block statement of the preceding switch labeled statement group.
*/
public void testBug548318_023() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 6)\n" +
" yield v;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 19)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v;\n" +
" int t = switch (i) {\n" +
" case 0 : {\n" +
" yield v;\n" +
" }\n" +
" case 2 : {\n" +
" yield 2;\n" +
" }\n" +
" default : {\n" +
" yield 3;\n" +
" }\n" +
" };\n" +
" return t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
* which are boolean-valued.
* V is [un]assigned before the first block statement of a switch labeled statement group (14.11.1) of a switch expression
* iff both of following are true:
* V is [un]assigned after the selector expression of the switch statement.
* If the switch labeled statement group is not the first in the switch block,
* V is [un]assigned after the last block statement of the preceding switch labeled statement group.
*/
public void testBug548318_024() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 9)\n" +
" yield v;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 19)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"public class X {\n" +
" public static int foo(int i) {\n" +
" int v ;\n" +
" int t = switch (i) {\n" +
" case 0 : {\n" +
" yield 1;\n" +
" }\n" +
" case 2 : {\n" +
" yield v;\n" +
" }\n" +
" default : {\n" +
" yield 3;\n" +
" }\n" +
" };\n" +
" return t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" System.out.println(foo(3));\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, V is [un]assigned after a switch expression (15.28) iff all of the following are true:
* V is [un]assigned before every yield statement that may exit the switch statement.
* For each switch labeled rule (14.11.1) in the switch block, V is [un]assigned after the
* expression, block, or throw statement of the switch labeled rule.
*/
public void testBug548318_025() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 20)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v ;\n" +
" int t = switch (i) {\n" +
" case 0 -> v = 1;\n" +
" case 2 -> {\n" +
" if (i > 1) {\n" +
" yield v = 2;\n" +
" }\n" +
" yield v = 3;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" return v + t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" // TODO Auto-generated catch block\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, V is [un]assigned after a switch expression (15.28) iff all of the following are true:
* V is [un]assigned before every yield statement that may exit the switch statement.
* For each switch labeled rule (14.11.1) in the switch block, V is [un]assigned after the
* expression, block, or throw statement of the switch labeled rule.
*/
public void testBug548318_026() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 16)\n" +
" return v + t;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 20)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v ;\n" +
" int t = switch (i) {\n" +
" case 0 -> 1;\n" +
" case 2 -> {\n" +
" if (i > 1) {\n" +
" yield 2;\n" +
" }\n" +
" yield 3;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" return v + t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" // TODO Auto-generated catch block\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
* which are boolean-valued.
* V is [un]assigned before the expression, block, or throw statement of a switch labeled rule of a
* switch expression iff V is [un]assigned after the selector expression of the switch expression.
*/
public void testBug548318_027() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 20)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v ;\n" +
" int t = switch (v = 1) {\n" +
" case 0 -> v;\n" +
" case 2 -> {\n" +
" if (i > 1) {\n" +
" yield 2;\n" +
" }\n" +
" yield 3;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" return v + t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" // TODO Auto-generated catch block\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
* which are boolean-valued.
* V is [un]assigned before the expression, block, or throw statement of a switch labeled rule of a
* switch expression iff V is [un]assigned after the selector expression of the switch expression.
*/
public void testBug548318_028() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 7)\n" +
" case 0 -> v;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 20)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v ;\n" +
" int t = switch (i) {\n" +
" case 0 -> v;\n" +
" case 2 -> {\n" +
" if (i > 1) {\n" +
" yield 2;\n" +
" }\n" +
" yield 3;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" return t;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" // TODO Auto-generated catch block\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.2.9, [tests the second rule - assigned]
* V is [un]assigned after a switch statement (14.11) iff all of the following are true:
* V is [un]assigned before every break statement that may exit the switch statement.
* For each switch labeled rule (14.11.1) in the switch block, V is [un]assigned after the
* expression, block, or throw statement of the switch labeled rule.
* If there is a switch labeled statement group (14.11.1) in the switch block, then V is [un]assigned
* after the last block statement of the last switch labeled statement group.
* If there is no default label in the switch block, or if the switch block ends with a switch label
* followed by }, then V is [un]assigned after the selector expression
*/
public void testBug548318_029() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 24)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v ;\n" +
" switch (i) {\n" +
" case 0 -> {\n" +
" v = 0;\n" +
" }\n" +
" case 2 -> {\n" +
" if (i > 1) {\n" +
" v = 2;\n" +
" break;\n" +
" }\n" +
" v = 3;\n" +
" break;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" return v;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" // TODO Auto-generated catch block\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
/**
* From JLS 13 16.2.9, [tests the second rule - unassigned]
* V is [un]assigned after a switch statement (14.11) iff all of the following are true:
* V is [un]assigned before every break statement that may exit the switch statement.
* For each switch labeled rule (14.11.1) in the switch block, V is [un]assigned after the
* expression, block, or throw statement of the switch labeled rule.
* If there is a switch labeled statement group (14.11.1) in the switch block, then V is [un]assigned
* after the last block statement of the last switch labeled statement group.
* If there is no default label in the switch block, or if the switch block ends with a switch label
* followed by }, then V is [un]assigned after the selector expression
*/
public void testBug548318_030() {
if (this.complianceLevel != ClassFileConstants.JDK13)
return;
Map<String, String> defaultOptions = super.getCompilerOptions();
defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
String expectedProblemLog =
"----------\n" +
"1. ERROR in X.java (at line 20)\n" +
" return v;\n" +
" ^\n" +
"The local variable v may not have been initialized\n" +
"----------\n" +
"2. ERROR in X.java (at line 24)\n" +
" Zork();\n" +
" ^^^^\n" +
"The method Zork() is undefined for the type X\n" +
"----------\n";
String[] testFiles = new String[] {
"X.java", // =================
"import java.io.IOException;\n" +
"\n" +
"public class X {\n" +
" public static int foo(int i) throws IOException {\n" +
" int v ;\n" +
" switch (i) {\n" +
" case 0 -> {\n" +
" v = 0;\n" +
" }\n" +
" case 2 -> {\n" +
" if (i > 1) {\n" +
" v = 2;\n" +
" break;\n" +
" }\n" +
" // v = 3;\n" +
" break;\n" +
" }\n" +
" default -> throw new IOException();\n" +
" };\n" +
" return v;\n" +
" }\n" +
" \n" +
" public boolean bar() {\n" +
" Zork();\n" +
" return true;\n" +
" }\n" +
" public static void main(String[] args) {\n" +
" try {\n" +
" System.out.println(foo(3));\n" +
" } catch (IOException e) {\n" +
" // TODO Auto-generated catch block\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
"}\n",
};
this.runNegativeTest(
testFiles,
expectedProblemLog,
null,
true,
defaultOptions);
}
public static Class testClass() {
return FlowAnalysisTest.class;
}
}