diff options
author | Stephan Herrmann | 2011-10-25 16:30:36 +0000 |
---|---|---|
committer | Stephan Herrmann | 2011-10-25 16:30:36 +0000 |
commit | 71432c0b3a7c9ea06e15185063ebff50c33d4643 (patch) | |
tree | e29b0104f05d122101a93d144c89c7ad8aa821d1 /org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core | |
parent | 6dcbb38068eee59acb310076b78bc9a8183f88b8 (diff) | |
download | org.eclipse.objectteams-71432c0b3a7c9ea06e15185063ebff50c33d4643.tar.gz org.eclipse.objectteams-71432c0b3a7c9ea06e15185063ebff50c33d4643.tar.xz org.eclipse.objectteams-71432c0b3a7c9ea06e15185063ebff50c33d4643.zip |
update sources to v_C18, build config to v_C17 (no build containing C18 is available at this point)
Diffstat (limited to 'org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core')
16 files changed, 3110 insertions, 119 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java index 8ff3a9e18..8c518e8b8 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; +import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -32,8 +33,10 @@ import java.util.Locale; import java.util.Map; import java.util.StringTokenizer; +import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.compiler.batch.BatchCompiler; @@ -2781,4 +2784,16 @@ protected void runNegativeTest( printJavacResultsSummary(); } } + /** + * Returns the OS path to the directory that contains this plugin. + */ + protected String getCompilerTestsPluginDirectoryPath() { + try { + URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.compiler").getEntry("/"); + return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java index 42ccda452..72307e8b2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 IBM Corporation and others. + * Copyright (c) 2005, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -1221,7 +1221,7 @@ public void test050() { "1. ERROR in p\\X.java (at line 4)\n" + " public static String s;\n" + " ^\n" + - "The field s cannot be declared static; static fields can only be declared in static or top level types\n" + + "The field s cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + "----------\n" + "2. ERROR in p\\X.java (at line 6)\n" + " X.XX.s = s; }\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java index f15f9de6a..ec8197cff 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java @@ -8,9 +8,12 @@ * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla - Contribution for bug 239066 - * Stephan Herrmann - Contribution for bug 236385 - * Stephan Herrmann - Contribution for bug 295551 - * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read + * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for + * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used + * bug 295551 - Add option to automatically promote all warnings to errors + * bug 185682 - Increment/decrement operators mark local variables as read + * bug 349326 - [1.7] new warning for missing try-with-resources + * bug 359721 - [options] add command line option for new warning token "resource" * Technical University Berlin - adapted for Object Teams *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -1669,6 +1672,7 @@ public void test012b(){ //OT (2x): " abstractrelevantrole + abstract relevant role (OTJLD 2.5(b))\n" + " adaptDeprecated + adapting a deprecated type/method\n" + + " all enable all warnings\n" + " allDeadCode dead code including trivial if(DEBUG) check\n" + " allDeprecation deprecation including inside deprecated code\n" + " allJavadoc invalid or missing javadoc\n" + @@ -1740,6 +1744,7 @@ public void test012b(){ " paramAssign assignment to a parameter\n" + " pkgDefaultMethod + attempt to override package-default method\n" + " raw + usage of raw type\n" + + " resource + (pot.) unsafe usage of resource of type Closeable\n" + //OT: " roleinstantiation + unsafe instantiation of a role\n" + " (OTJLD 2.4.1(c), 2.4.3)\n" + @@ -1861,6 +1866,7 @@ public void test012b(){ " <option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + + " <option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" + @@ -1902,6 +1908,7 @@ public void test012b(){ " <option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + + " <option key=\"org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments\" value=\"ignore\"/>\n" + @@ -1917,6 +1924,7 @@ public void test012b(){ " <option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" + + " <option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + " <option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + @@ -6942,7 +6950,7 @@ public void test174_warn_options() { "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + " } catch (E1 e1) {\n" + " ^^\n" + - "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + + "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + "----------\n" + "3 problems (3 warnings)", true); @@ -7010,7 +7018,7 @@ public void test175_warn_options() { "4. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + " } catch (E1 e1) {\n" + " ^^\n" + - "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + + "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + "----------\n" + "4 problems (4 warnings)", true); @@ -7145,7 +7153,7 @@ public void test178_warn_options() { "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + " } catch (E1 e1) {\n" + " ^^\n" + - "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + + "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + "----------\n" + "1 problem (1 warning)", true); @@ -7245,7 +7253,7 @@ public void test180_warn_options() { "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + " } catch (E1 e1) {\n" + " ^^\n" + - "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + + "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + "----------\n" + "3 problems (3 warnings)", true); @@ -7300,7 +7308,7 @@ public void test181_warn_options() { "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + " } catch (E1 e1) {\n" + " ^^\n" + - "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + + "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + "----------\n" + "3 problems (3 warnings)", true); @@ -7410,7 +7418,7 @@ public void test183_warn_options() { "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + " } catch (E1 e1) {\n" + " ^^\n" + - "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + + "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + "----------\n" + "3 problems (3 warnings)", true); @@ -8580,48 +8588,6 @@ public void test213_warn_options() { "1 problem (1 warning)", true); } -// https://bugs.eclipse.org/bugs/show_bug.cgi?id=210518 -// variant -public void test214_warn_options() { - // same source as 153, skip default checks - this.runNegativeTest( - new String[] { - "X.java", - "public class X {\n" + - " public static void foo() {\n" + - " String s = null;\n" + - " s.toString();\n" + - " String u;\n" + - " }\n" + - "}", - }, - "\"" + OUTPUT_DIR + File.separator + "X.java\"" - + " -warn:null,-unused -proc:none -d \"" + OUTPUT_DIR + "\"", - "", - "usage of \'-\' for \'-unused\' is illegal there\n", - true); -} -// https://bugs.eclipse.org/bugs/show_bug.cgi?id=210518 -// variant -public void test215_warn_options() { - // same source as 153, skip default checks - this.runNegativeTest( - new String[] { - "X.java", - "public class X {\n" + - " public static void foo() {\n" + - " String s = null;\n" + - " s.toString();\n" + - " String u;\n" + - " }\n" + - "}", - }, - "\"" + OUTPUT_DIR + File.separator + "X.java\"" - + " -warn:null,+unused -proc:none -d \"" + OUTPUT_DIR + "\"", - "", - "usage of \'+\' for \'+unused\' is illegal there\n", - true); -} // https://bugs.eclipse.org/bugs/show_bug.cgi?id=211588 // variant - check impact of javadoc upon other warnings public void _test216a_warn_options() { @@ -11468,24 +11434,6 @@ public void test294(){ true); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784 -public void test295(){ - this.runNegativeTest( - new String[] { - "src/X.java", - "public class X {\n" + - "}", - }, - "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" - + " -cp \"" + LIB_DIR + "\"" - + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\"" - + " -1.5 -g -preserveAllLocals" - + " -proceedOnError -referenceInfo -err:raw,+discouraged" - + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ", - "", - "usage of \'+\' for \'+discouraged\' is illegal there\n", - true); -} -//https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784 public void test296(){ this.runNegativeTest( new String[] { @@ -12365,4 +12313,53 @@ public void testReportingUnavoidableGenericProblems2() { "3 problems (1 error, 2 warnings)", true); } +//-warn option - regression tests +public void test0308_warn_options() { + // check the option introduced in bug 359721 + this.runConformTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo() throws java.io.IOException {\n" + + " FileReader r = new FileReader(\"f1\");\n" + + " char[] cs = new char[1024];\n" + + " r.read(cs);\n" + + " }\n" + + "}\n" + }, + "\"" + OUTPUT_DIR + File.separator + "X.java\"" + + " -warn:-resource -1.7 -d \"" + OUTPUT_DIR + "\"", + "", + "", + true); +} +//-warn option - regression tests +public void test0309_warn_options() { + // check the option introduced in bug 359721 + this.runConformTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo(boolean b) throws java.io.IOException {\n" + + " FileReader r = new FileReader(\"f1\");\n" + + " char[] cs = new char[1024];\n" + + " r.read(cs);\n" + + " if (b) r.close();\n" + + " }\n" + + "}\n" + }, + "\"" + OUTPUT_DIR + File.separator + "X.java\"" + + " -warn:+resource -1.7 -d \"" + OUTPUT_DIR + "\"", + "", + "----------\n" + + "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 4)\n" + + " FileReader r = new FileReader(\"f1\");\n" + + " ^\n" + + "Potential resource leak: \'r\' may not be closed\n" + + "----------\n" + + "1 problem (1 warning)", + true); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java new file mode 100644 index 000000000..15d6b0155 --- /dev/null +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.compiler.regression; + +import java.io.File; + +import junit.framework.Test; + +import org.eclipse.jdt.core.ToolFactory; +import org.eclipse.jdt.core.tests.util.Util; +import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; + +public class BootstrapMethodAttributeTest extends AbstractRegressionTest { + public BootstrapMethodAttributeTest(String name) { + super(name); + } + + public static Class testClass() { + return BootstrapMethodAttributeTest.class; + } + + // Use this static initializer to specify subset for tests + // All specified tests which does not belong to the class are skipped... + static { +// TESTS_PREFIX = "testBug95521"; +// TESTS_NAMES = new String[] { "testBug359495" }; +// TESTS_NUMBERS = new int[] { 53 }; +// TESTS_RANGE = new int[] { 23 -1,}; + } + public static Test suite() { + return buildMinimalComplianceTestSuite(testClass(), F_1_7); + } + public void test001() throws Exception { + + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + String path = this.getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator + "TestBootstrapMethodAtt.class"; + byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(path)); + String actualOutput = + disassembler.disassemble( + classFileBytes, + "\n", + ClassFileBytesDisassembler.DETAILED); + + String expectedOutput = + "// (version 1.2 : 46.0, no super bit)\n" + + "public class test.G {\n" + + " \n" + + " // Method descriptor #2 ()V\n" + + " // Stack: 0, Locals: 0\n" + + " public static void call();\n" + + " 0 invokedynamic 0 dyn() : void [18]\n" + + " 5 return\n" + + "\n" + + "Bootstrap methods:\n" + + " 0 : # 17 arguments: {#1}\n" + + "}"; + + int index = actualOutput.indexOf(expectedOutput); + if (index == -1 || expectedOutput.length() == 0) { + System.out.println(Util.displayString(actualOutput, 2)); + } + if (index == -1) { + assertEquals("Wrong contents", expectedOutput, actualOutput); + } + } +} diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java index e43338151..bbd1f0705 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java @@ -8,7 +8,9 @@ * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla - Contribution for bug 239066 - * Stephan Herrmann - Contribution for bug 236385 + * 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 * Stephan Herrmann - Adjustments for Object Teams *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -444,6 +446,7 @@ public void _test011_problem_categories() { expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED); expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED); expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED); + expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); @@ -769,6 +772,8 @@ public void _test011_problem_categories() { expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW)); + expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); + expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); @@ -808,6 +813,7 @@ public void _test011_problem_categories() { expectedProblemAttributes.put("SuperclassNotFound", DEPRECATED); expectedProblemAttributes.put("SuperclassNotVisible", DEPRECATED); expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); + expectedProblemAttributes.put("SwitchOnEnumNotBelow15", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("SwitchOnStringsNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("Task", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); expectedProblemAttributes.put("ThisInStaticContext", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); @@ -832,6 +838,8 @@ public void _test011_problem_categories() { expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT)); expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); + expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); + expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); @@ -1193,6 +1201,7 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP); expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP); expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP); + expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE)); expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP); expectedProblemAttributes.put("ExternalProblemFixable", SKIP); expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP); @@ -1518,6 +1527,8 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP); expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT)); expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION)); + expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE)); + expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE)); expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE)); expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP); expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP); @@ -1557,6 +1568,7 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("SuperclassNotFound", SKIP); expectedProblemAttributes.put("SuperclassNotVisible", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_SUPERINTERFACE)); expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(JavaCore.COMPILER_PB_EMPTY_STATEMENT)); + expectedProblemAttributes.put("SwitchOnEnumNotBelow15", SKIP); expectedProblemAttributes.put("SwitchOnStringsNotBelow17", SKIP); expectedProblemAttributes.put("Task", SKIP); expectedProblemAttributes.put("ThisInStaticContext", SKIP); @@ -1581,6 +1593,8 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION)); expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING)); expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING)); + expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE)); + expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE)); expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP); expectedProblemAttributes.put("UndefinedConstructor", SKIP); expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP); diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java index 66eeb0d6c..f63a0609a 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java @@ -1119,7 +1119,7 @@ public void test020() { "1. ERROR in X.java (at line 4)\n" + " static final String notAConstant = null;\n" + " ^^^^^^^^^^^^\n" + - "The field notAConstant cannot be declared static; static fields can only be declared in static or top level types\n" + + "The field notAConstant cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + "----------\n"); } public void testAllConstants() { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java index b9f580f25..aa4d4729e 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java @@ -3761,7 +3761,7 @@ public void test113() { "1. ERROR in X.java (at line 3)\n" + " static int bar;\n" + " ^^^\n" + - "The field bar cannot be declared static; static fields can only be declared in static or top level types\n" + + "The field bar cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + "----------\n"); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=99428 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=99655 diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java index 32b50af3e..f197e7dab 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java @@ -7,7 +7,10 @@ * * Contributors: * IBM Corporation - initial API and implementation - * Stephan Herrmann - Contribution for bug 236385 + * 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) *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -28,6 +31,7 @@ import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; public class FlowAnalysisTest extends AbstractRegressionTest { static { +// TESTS_NAMES = new String[] { "testLocalClassInInitializer1" }; // TESTS_NUMBERS = new int[] { 69 }; } public FlowAnalysisTest(String name) { @@ -2360,6 +2364,132 @@ public void testBug338234d() { "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() { + 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"); +} +// 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() { + 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" + }, + ""); +} +// 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"); +} public static Class testClass() { return FlowAnalysisTest.class; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java index 56c50ae67..f1d190bbb 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java @@ -11238,25 +11238,7 @@ public void test199() { } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=285088 public void test200() { - Map options = getCompilerOptions(); - String compliance = (String) options.get(JavaCore.COMPILER_COMPLIANCE); - String errorMessage = compliance == JavaCore.VERSION_1_6 ? - "----------\n" + - "1. WARNING in X.java (at line 3)\n" + - " int foo(Collection bar) { return 0; }\n" + - " ^^^^^^^^^^^^^^^^^^^\n" + - "Method foo(Collection) has the same erasure foo(Collection<E>) as another method in type X\n" + - "----------\n" + - "2. WARNING in X.java (at line 3)\n" + - " int foo(Collection bar) { return 0; }\n" + - " ^^^^^^^^^^\n" + - "Collection is a raw type. References to generic type Collection<E> should be parameterized\n" + - "----------\n" + - "3. WARNING in X.java (at line 4)\n" + - " double foo(Collection<String> bar) {return 0; }\n" + - " ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Method foo(Collection<String>) has the same erasure foo(Collection<E>) as another method in type X\n" + - "----------\n" : + String errorMessage = "----------\n" + "1. ERROR in X.java (at line 3)\n" + " int foo(Collection bar) { return 0; }\n" + @@ -13439,7 +13421,7 @@ public void testBug317719h() throws Exception { String output = this.complianceLevel == ClassFileConstants.JDK1_6 ? "----------\n" + "1. WARNING in Test.java (at line 3)\n" + - " public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" + + " public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" + " ^^^^\n" + "The serializable class Test does not declare a static final serialVersionUID field of type long\n" + "----------\n" + @@ -13451,7 +13433,7 @@ public void testBug317719h() throws Exception { "3. WARNING in Test.java (at line 5)\n" + " public Collection<Value> get(Key k) { return null; }\n" + " ^^^^^^^^^^\n" + - "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type LinkedHashMap<K,V> but does not override it\n" + + "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type HashMap<K,V> but does not override it\n" + "----------\n" + "4. ERROR in Test.java (at line 6)\n" + " Zork z;\n" + @@ -13460,7 +13442,7 @@ public void testBug317719h() throws Exception { "----------\n": "----------\n" + "1. WARNING in Test.java (at line 3)\n" + - " public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" + + " public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" + " ^^^^\n" + "The serializable class Test does not declare a static final serialVersionUID field of type long\n" + "----------\n" + @@ -13472,7 +13454,7 @@ public void testBug317719h() throws Exception { "3. ERROR in Test.java (at line 5)\n" + " public Collection<Value> get(Key k) { return null; }\n" + " ^^^^^^^^^^\n" + - "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type LinkedHashMap<K,V> but does not override it\n" + + "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type HashMap<K,V> but does not override it\n" + "----------\n" + "4. ERROR in Test.java (at line 6)\n" + " Zork z;\n" + @@ -13483,8 +13465,8 @@ public void testBug317719h() throws Exception { new String[] { "Test.java", "import java.util.Collection;\n" + - "import java.util.LinkedHashMap;\n" + - "public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" + + "import java.util.HashMap;\n" + + "public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" + " public Collection<Value> put(Key k, Value v) { return null; }\n" + " public Collection<Value> get(Key k) { return null; }\n" + " Zork z;\n" + @@ -13512,4 +13494,50 @@ public void test345949a() throws Exception { "Name clash: The method foo(A<Integer>) of type Sub has the same erasure as foo(A<Number>) of type Super but does not hide it\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355838 +public void testBug355838() throws Exception { + String output = + "----------\n" + + "1. ERROR in ErasureBug.java (at line 4)\n" + + " public String output(List<String> integers) {\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Method output(List<String>) has the same erasure output(List<E>) as another method in type ErasureBug\n" + + "----------\n" + + "2. ERROR in ErasureBug.java (at line 7)\n" + + " public String output(List doubles) {\n" + + " ^^^^^^^^^^^^^^^^^^^^\n" + + "Method output(List) has the same erasure output(List<E>) as another method in type ErasureBug\n" + + "----------\n" + + "3. WARNING in ErasureBug.java (at line 7)\n" + + " public String output(List doubles) {\n" + + " ^^^^\n" + + "List is a raw type. References to generic type List<E> should be parameterized\n" + + "----------\n" + + "4. WARNING in ErasureBug.java (at line 10)\n" + + " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" + + " ^^^^^^^^^^^^^^^\n" + + "Type safety: The expression of type ArrayList needs unchecked conversion to conform to List<String>\n" + + "----------\n" + + "5. WARNING in ErasureBug.java (at line 10)\n" + + " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" + + " ^^^^^^^^^\n" + + "ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized\n" + + "----------\n"; + this.runNegativeTest( + new String[] { + "ErasureBug.java", + "import java.util.ArrayList;\n" + + "import java.util.List;\n" + + "public class ErasureBug {\n" + + " public String output(List<String> integers) {\n" + + " return \"1\";\n" + + " }\n" + + " public String output(List doubles) {\n" + + " return \"2\";\n" + + " }\n" + + " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" + + "}\n" + }, + output); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java index f3355b450..1ac26d01f 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java @@ -18,6 +18,9 @@ * bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop * bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself * bug 354554 - [null] conditional with redundant condition yields weak error message + * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis + * 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) *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; @@ -45,7 +48,7 @@ public NullReferenceTest(String name) { // Only the highest compliance level is run; add the VM argument // -Dcompliance=1.4 (for example) to lower it if needed static { -// TESTS_NAMES = new String[] { "testBug348379" }; +// TESTS_NAMES = new String[] { "testBug360328" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } @@ -6031,12 +6034,17 @@ public void test0562_try_catch_unchecked_exception() { " }\n" + " }\n" + "}\n"}, - "----------\n" + - "1. ERROR in X.java (at line 8)\n" + - " o.toString();\n" + - " ^\n" + - "Potential null pointer access: The variable o may be null at this location\n" + - "----------\n", + "----------\n" + + "1. WARNING in X.java (at line 6)\n" + + " o = new LineNumberReader(new FileReader(\"dummy\"));\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'o' is never closed\n" + + "----------\n" + + "2. ERROR in X.java (at line 8)\n" + + " o.toString();\n" + + " ^\n" + + "Potential null pointer access: The variable o may be null at this location\n" + + "----------\n", JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); } @@ -14946,4 +14954,448 @@ public void testBug354554b() { "Redundant null check: The variable u cannot be null at this location\n" + "----------\n"); } +// Bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis +public void test358827() { + if (this.complianceLevel >= ClassFileConstants.JDK1_7) { + this.runNegativeTest( + new String[] { + "Bug358827.java", + "import java.io.FileReader;\n" + + "public class Bug358827 {\n" + + " Object foo2() throws Exception {\n" + + " String o = null;\n" + + " try (FileReader rf = new FileReader(\"file\")){\n" + + " o = o.toUpperCase();\n" + + " } finally {\n" + + " o = \"OK\";\n" + + " }\n" + + " return o;\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in Bug358827.java (at line 6)\n" + + " o = o.toUpperCase();\n" + + " ^\n" + + "Null pointer access: The variable o can only be null at this location\n" + + "----------\n"); + } +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796 +public void testBug256796() { + Map compilerOptions = getCompilerOptions(); + compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE); + compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING); + compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.DISABLED); + this.runNegativeTest( + new String[] { + "Bug.java", + "public class Bug {\n" + + " private static final boolean TRUE = true;\n" + + " private static final boolean FALSE = false;\n" + + " void foo() throws Exception {\n" + + " if (TRUE) return;\n" + + " else System.out.println(\"\");\n" + + " System.out.println(\"\");\n" + // not dead code + " if (TRUE) throw new Exception();\n" + + " else System.out.println(\"\");\n" + + " System.out.println(\"\");\n" + // not dead code + " if (TRUE) return;\n" + + " System.out.println(\"\");\n" + // not dead code + " if (FALSE) System.out.println(\"\");\n" + + " else return;\n" + + " System.out.println(\"\");\n" + // not dead code + " if (FALSE) return;\n" + + " System.out.println(\"\");\n" + // not dead code + " if (false) return;\n" + // dead code + " System.out.println(\"\");\n" + + " if (true) return;\n" + + " System.out.println(\"\");\n" + // dead code + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in Bug.java (at line 18)\n" + + " if (false) return;\n" + + " ^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "2. WARNING in Bug.java (at line 21)\n" + + " System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n", + null, + true, + compilerOptions); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796 +public void testBug256796a() { + Map compilerOptions = getCompilerOptions(); + compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE); + compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING); + compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.ENABLED); + this.runNegativeTest( + new String[] { + "Bug.java", + "public class Bug {\n" + + " private static final boolean TRUE = true;\n" + + " private static final boolean FALSE = false;\n" + + " void foo() throws Exception {\n" + + " if (TRUE) return;\n" + + " else System.out.println(\"\");\n" + + " System.out.println(\"\");\n" + // dead code + " }\n" + + " void foo2() {\n" + + " if (TRUE) return;\n" + + " System.out.println(\"\");\n" + // dead code + " }\n" + + " void foo3() throws Exception {\n" + + " if (TRUE) throw new Exception();\n" + + " else System.out.println(\"\");\n" + // dead code + " System.out.println(\"\");\n" + // dead code + " }\n" + + " void foo4() throws Exception {\n" + + " if (FALSE) System.out.println(\"\");\n" + + " else return;\n" + + " System.out.println(\"\");\n" + // dead code + " }\n" + + " void foo5() throws Exception {\n" + + " if (FALSE) return;\n" + // dead code + " System.out.println(\"\");\n" + + " }\n" + + " void foo6() throws Exception {\n" + + " if (false) return;\n" + // dead code + " System.out.println(\"\");\n" + + " if (true) return;\n" + + " System.out.println(\"\");\n" + // dead code + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in Bug.java (at line 6)\n" + + " else System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "2. WARNING in Bug.java (at line 7)\n" + + " System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "3. WARNING in Bug.java (at line 11)\n" + + " System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "4. WARNING in Bug.java (at line 15)\n" + + " else System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "5. WARNING in Bug.java (at line 16)\n" + + " System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "6. WARNING in Bug.java (at line 19)\n" + + " if (FALSE) System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "7. WARNING in Bug.java (at line 21)\n" + + " System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "8. WARNING in Bug.java (at line 24)\n" + + " if (FALSE) return;\n" + + " ^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "9. WARNING in Bug.java (at line 28)\n" + + " if (false) return;\n" + + " ^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "10. WARNING in Bug.java (at line 31)\n" + + " System.out.println(\"\");\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n", + null, + true, + compilerOptions); +} +// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) +public void testBug360328() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); + runNegativeTest( + true, /* flushOutputDir */ + new String[] { + "X.java", + "public class X {\n" + + " void print4() {\n" + + " final String s1 = \"\";\n" + + " for (int i=0; i<4; i++)\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " if (s1 != null)\n" + + " s1.toString();\n" + + " }\n" + + " }.run();\n" + + " }\n" + + " void print16(boolean b) {\n" + + " final String s3 = b ? null : \"\";\n" + + " for (int i=0; i<16; i++)\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " s3.toString();\n" + + " }\n" + + " }.run();\n" + + " }\n" + + " void print23() {\n" + + " final String s23 = null;\n" + + " for (int i=0; i<23; i++)\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " s23.toString();\n" + + " }\n" + + " }.run();\n" + + " }\n" + + "}\n", + + }, + null, /* classLibs */ + customOptions, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " if (s1 != null)\n" + + " ^^\n" + + "Redundant null check: The variable s1 cannot be null at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 17)\n" + + " s3.toString();\n" + + " ^^\n" + + "Potential null pointer access: The variable s3 may be null at this location\n" + + "----------\n" + + "3. ERROR in X.java (at line 26)\n" + + " s23.toString();\n" + + " ^^^\n" + + "Null pointer access: The variable s23 can only be null at this location\n" + + "----------\n", + "",/* expected output */ + "",/* expected error */ + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} +// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) +// constructors +public void testBug360328b() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); + runNegativeTest( + true, /* flushOutputDir */ + new String[] { + "X.java", + "public class X {\n" + + " void print4() {\n" + + " final String s1 = \"\";\n" + + " for (int i=0; i<4; i++) {\n" + + " class R {\n" + + " public R() {\n" + + " if (s1 != null)\n" + + " s1.toString();\n" + + " }\n" + + " };\n" + + " new R();\n" + + " }\n" + + " }\n" + + " void print16(boolean b) {\n" + + " final String s3 = b ? null : \"\";\n" + + " int i=0; while (i++<16) {\n" + + " class R {\n" + + " public R() {\n" + + " s3.toString();\n" + + " }\n" + + " };\n" + + " new R();\n" + + " };\n" + + " }\n" + + " void print23() {\n" + + " final String s23 = null;\n" + + " for (int i=0; i<23; i++) {\n" + + " class R {\n" + + " public R() {\n" + + " s23.toString();\n" + + " }\n" + + " };\n" + + " new R();\n" + + " };\n" + + " }\n" + + "}\n", + + }, + null, /* classLibs */ + customOptions, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " if (s1 != null)\n" + + " ^^\n" + + "Redundant null check: The variable s1 cannot be null at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 19)\n" + + " s3.toString();\n" + + " ^^\n" + + "Potential null pointer access: The variable s3 may be null at this location\n" + + "----------\n" + + "3. ERROR in X.java (at line 30)\n" + + " s23.toString();\n" + + " ^^^\n" + + "Null pointer access: The variable s23 can only be null at this location\n" + + "----------\n", + "",/* expected output */ + "",/* expected error */ + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} +// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) +// initializers +public void testBug360328c() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE); + runNegativeTest( + true, /* flushOutputDir */ + new String[] { + "X.java", + "public class X {\n" + + " void print4() {\n" + + " final String s1 = \"\";\n" + + " for (int i=0; i<4; i++) {\n" + + " class R {\n" + + " String s1R;\n" + + " {\n" + + " if (s1 != null)\n" + + " s1R = s1;\n" + + " }\n" + + " };\n" + + " new R();\n" + + " }\n" + + " }\n" + + " void print16(boolean b) {\n" + + " final String s3 = b ? null : \"\";\n" + + " for (int i=0; i<16; i++) {\n" + + " class R {\n" + + " String s3R = s3.toString();\n" + + " };\n" + + " new R();\n" + + " };\n" + + " }\n" + + " void print23() {\n" + + " final String s23 = null;\n" + + " for (int i=0; i<23; i++) {\n" + + " class R {\n" + + " String s23R;\n" + + " {\n" + + " s23R = s23.toString();\n" + + " }\n" + + " };\n" + + " new R();\n" + + " };\n" + + " }\n" + + "}\n", + + }, + null, /* classLibs */ + customOptions, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " if (s1 != null)\n" + + " ^^\n" + + "Redundant null check: The variable s1 cannot be null at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 19)\n" + + " String s3R = s3.toString();\n" + + " ^^\n" + + "Potential null pointer access: The variable s3 may be null at this location\n" + + "----------\n" + + "3. ERROR in X.java (at line 30)\n" + + " s23R = s23.toString();\n" + + " ^^^\n" + + "Null pointer access: The variable s23 can only be null at this location\n" + + "----------\n", + "",/* expected output */ + "",/* expected error */ + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} +// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) +// try-finally instead of loop +public void testBug360328d() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); + customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); + runNegativeTest( + true, /* flushOutputDir */ + new String[] { + "X.java", + "public class X {\n" + + " void print4() {\n" + + " final String s1 = \"\";\n" + + " try { } finally {\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " if (s1 != null)\n" + + " s1.toString();\n" + + " }\n" + + " }.run();\n" + + " }\n" + + " }\n" + + " void print16(boolean b) {\n" + + " final String s3 = b ? null : \"\";\n" + + " try { } finally {\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " s3.toString();\n" + + " }\n" + + " }.run();\n" + + " }\n" + + " }\n" + + " void print23() {\n" + + " final String s23 = null;\n" + + " try { } finally {\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " s23.toString();\n" + + " }\n" + + " }.run();\n" + + " }\n" + + " }\n" + + "}\n", + + }, + null, /* classLibs */ + customOptions, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " if (s1 != null)\n" + + " ^^\n" + + "Redundant null check: The variable s1 cannot be null at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 18)\n" + + " s3.toString();\n" + + " ^^\n" + + "Potential null pointer access: The variable s3 may be null at this location\n" + + "----------\n" + + "3. ERROR in X.java (at line 28)\n" + + " s23.toString();\n" + + " ^^^\n" + + "Null pointer access: The variable s23 can only be null at this location\n" + + "----------\n", + "",/* expected output */ + "",/* expected error */ + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} }
\ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java index a551aa001..3b4db3713 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java @@ -7076,4 +7076,116 @@ public void test124b() { compilerOptions /* custom options */ ); } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=354502 +// Anonymous class instantiation of a non-static member type, method can't be static +public void test354502() { + if (this.complianceLevel < ClassFileConstants.JDK1_5) + return; + Map compilerOptions = getCompilerOptions(); + compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR); + compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.ERROR); + compilerOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public abstract class Abstract{}\n" + + " public static abstract class Abstract2{}\n" + + " private void method1() {\n" + // don't warn + " new Abstract() {};\n" + + " }\n" + + " private void method2() {\n" + // warn + " new Abstract2() {};\n" + + " }\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " private void method2() {\n" + + " ^^^^^^^^^\n" + + "The method method2() from the type X can be declared as static\n" + + "----------\n", + null /* no extra class libraries */, + true /* flush output directory */, + compilerOptions /* custom options */ + ); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164 +public void test360164() { + if (this.complianceLevel < ClassFileConstants.JDK1_5) return; + this.runConformTest( + new String[] { + "p/B.java", + "package p;\n" + + "\n" + + "public abstract class B<K,V> {\n" + + " protected abstract V foo(K element);\n" + + "}\n", + "p/C.java", + "package p;\n" + + "public class C {\n" + + "}\n", + "p/D.java", + "package p;\n" + + "public class D extends E {\n" + + "}\n", + "p/E.java", + "package p;\n" + + "public abstract class E implements I {\n" + + "}\n", + "p/I.java", + "package p;\n" + + "public interface I {\n" + + "}\n", + "p/X.java", + "package p;\n" + + "public class X {\n" + + " private final class A extends B<C,D>{\n" + + " @Override\n" + + " protected D foo(C c) {\n" + + " return null;\n" + + " }\n" + + " }\n" + + "}\n", + }, + ""); + + // delete binary file I (i.e. simulate removing it from classpath for subsequent compile) + Util.delete(new File(OUTPUT_DIR, "p" + File.separator + "I.class")); + + runNegativeTest( + // test directory preparation + false /* do not flush output directory */, + new String[] { /* test files */ + "p/X.java", + "package p;\n" + + "public class X {\n" + + " private final class A extends B<C,D>{\n" + + " @Override\n" + + " protected D foo(C c) {\n" + + " Zork z;\n" + + " return null;\n" + + " }\n" + + " }\n" + + "}\n", + }, + // compiler options + null /* no class libraries */, + null /* no custom options */, + // compiler results + "----------\n" + + "1. WARNING in p\\X.java (at line 3)\n" + + " private final class A extends B<C,D>{\n" + + " ^\n" + + "The type X.A is never used locally\n" + + "----------\n" + + "2. ERROR in p\\X.java (at line 6)\n" + + " Zork z;\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n", + // javac options + JavacTestOptions.SKIP_UNTIL_FRAMEWORK_FIX /* javac test options */); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java index de0e7c619..afc568e8d 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java @@ -33,7 +33,7 @@ public class StackMapAttributeTest extends AbstractRegressionTest { // All specified tests which does not belong to the class are skipped... static { // TESTS_PREFIX = "testBug95521"; -// TESTS_NAMES = new String[] { "testBug83127a" }; +// TESTS_NAMES = new String[] { "testBug359495" }; // TESTS_NUMBERS = new int[] { 53 }; // TESTS_RANGE = new int[] { 23 -1,}; } @@ -6802,4 +6802,207 @@ public class StackMapAttributeTest extends AbstractRegressionTest { }, "SUCCESS"); } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495 + public void testBug359495a() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "import java.util.List;\n" + + "import java.util.concurrent.locks.Lock;\n" + + "import java.util.Arrays;\n" + + "import java.util.concurrent.locks.ReentrantLock;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " final Lock lock = new ReentrantLock();\n" + + " final List<String> strings = Arrays.asList(args);\n" + + " lock.lock();\n" + + " try{\n" + + " for (final String string:strings){\n" + + " return;\n" + + " }\n" + + " return;\n" + + " } finally {\n" + + " lock.unlock();\n" + + " }" + + " }\n" + + "}", + }, + ""); + + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); + String actualOutput = + disassembler.disassemble( + classFileBytes, + "\n", + ClassFileBytesDisassembler.DETAILED); + + String expectedOutput = + " // Method descriptor #15 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 6\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" + + " 3 dup\n" + + " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" + + " 7 astore_1 [lock]\n" + + " 8 aload_0 [args]\n" + + " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" + + " 12 astore_2 [strings]\n" + + " 13 aload_1 [lock]\n" + + " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" + + " 19 aload_2 [strings]\n" + + " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" + + " 25 astore 4\n" + + " 27 aload 4\n" + + " 29 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" + + " 34 ifeq 55\n" + + " 37 aload 4\n" + + " 39 invokeinterface java.util.Iterator.next() : java.lang.Object [42] [nargs: 1]\n" + + " 44 checkcast java.lang.String [46]\n" + + " 47 astore_3 [string]\n" + + " 48 aload_1 [lock]\n" + + " 49 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + + " 54 return\n" + + " 55 aload_1 [lock]\n" + + " 56 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + + " 61 return\n" + + " 62 astore 5\n" + + " 64 aload_1 [lock]\n" + + " 65 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + + " 70 aload 5\n" + + " 72 athrow\n" + + " Exception Table:\n" + + " [pc: 19, pc: 48] -> 62 when : any\n" + + " Line numbers:\n" + + " [pc: 0, line: 7]\n" + + " [pc: 8, line: 8]\n" + + " [pc: 13, line: 9]\n" + + " [pc: 19, line: 11]\n" + + " [pc: 48, line: 16]\n" + + " [pc: 54, line: 12]\n" + + " [pc: 55, line: 16]\n" + + " [pc: 61, line: 14]\n" + + " [pc: 62, line: 15]\n" + + " [pc: 64, line: 16]\n" + + " [pc: 70, line: 17]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 73] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 8, pc: 73] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" + + " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List\n" + + " [pc: 48, pc: 55] local: string index: 3 type: java.lang.String\n" + + " Local variable type table:\n" + + " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List<java.lang.String>\n" + + " Stack map table: number of frames 2\n" + + " [pc: 55, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" + + " [pc: 62, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n" ; + + int index = actualOutput.indexOf(expectedOutput); + if (index == -1 || expectedOutput.length() == 0) { + System.out.println(Util.displayString(actualOutput, 2)); + } + if (index == -1) { + assertEquals("Wrong contents", expectedOutput, actualOutput); + } + } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495 + public void testBug359495b() throws Exception { + this.runConformTest( + new String[] { + "X.java", + "import java.util.List;\n" + + "import java.util.Iterator;\n" + + "import java.util.concurrent.locks.Lock;\n" + + "import java.util.Arrays;\n" + + "import java.util.concurrent.locks.ReentrantLock;\n" + + "public class X {\n" + + " public static void main(String[] args) {\n" + + " final Lock lock = new ReentrantLock();\n" + + " final List<String> strings = Arrays.asList(args);\n" + + " lock.lock();\n" + + " try{\n" + + " for (Iterator i = strings.iterator(); i.hasNext();){\n" + + " return;\n" + + " }\n" + + " return;\n" + + " } finally {\n" + + " lock.unlock();\n" + + " }" + + " }\n" + + "}", + }, + ""); + + ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); + byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); + String actualOutput = + disassembler.disassemble( + classFileBytes, + "\n", + ClassFileBytesDisassembler.DETAILED); + + String expectedOutput = + " // Method descriptor #15 ([Ljava/lang/String;)V\n" + + " // Stack: 2, Locals: 5\n" + + " public static void main(java.lang.String[] args);\n" + + " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" + + " 3 dup\n" + + " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" + + " 7 astore_1 [lock]\n" + + " 8 aload_0 [args]\n" + + " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" + + " 12 astore_2 [strings]\n" + + " 13 aload_1 [lock]\n" + + " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" + + " 19 aload_2 [strings]\n" + + " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" + + " 25 astore_3 [i]\n" + + " 26 aload_3 [i]\n" + + " 27 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" + + " 32 ifeq 42\n" + + " 35 aload_1 [lock]\n" + + " 36 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + + " 41 return\n" + + " 42 aload_1 [lock]\n" + + " 43 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + + " 48 return\n" + + " 49 astore 4\n" + + " 51 aload_1 [lock]\n" + + " 52 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + + " 57 aload 4\n" + + " 59 athrow\n" + + " Exception Table:\n" + + " [pc: 19, pc: 35] -> 49 when : any\n" + + " Line numbers:\n" + + " [pc: 0, line: 8]\n" + + " [pc: 8, line: 9]\n" + + " [pc: 13, line: 10]\n" + + " [pc: 19, line: 12]\n" + + " [pc: 35, line: 17]\n" + + " [pc: 41, line: 13]\n" + + " [pc: 42, line: 17]\n" + + " [pc: 48, line: 15]\n" + + " [pc: 49, line: 16]\n" + + " [pc: 51, line: 17]\n" + + " [pc: 57, line: 18]\n" + + " Local variable table:\n" + + " [pc: 0, pc: 60] local: args index: 0 type: java.lang.String[]\n" + + " [pc: 8, pc: 60] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" + + " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List\n" + + " [pc: 26, pc: 42] local: i index: 3 type: java.util.Iterator\n" + + " Local variable type table:\n" + + " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List<java.lang.String>\n" + + " Stack map table: number of frames 2\n" + + " [pc: 42, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" + + " [pc: 49, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n"; + + int index = actualOutput.indexOf(expectedOutput); + if (index == -1 || expectedOutput.length() == 0) { + System.out.println(Util.displayString(actualOutput, 2)); + } + if (index == -1) { + assertEquals("Wrong contents", expectedOutput, actualOutput); + } + } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java index bae6a3c01..78f8badf0 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java @@ -2484,10 +2484,10 @@ public class StaticImportTest extends AbstractComparableTest { "}\n", }, "----------\n" + - "1. ERROR in p1\\A.java (at line 7)\n" + - " int v2 = b.fooC;\n" + + "1. ERROR in p1\\A.java (at line 6)\n" + + " int v1 = b.fooB;\n" + " ^^^^\n" + - "fooC cannot be resolved or is not a field\n" + + "fooB cannot be resolved or is not a field\n" + "----------\n"); } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=256375 @@ -2720,5 +2720,175 @@ public class StaticImportTest extends AbstractComparableTest { "----------\n" ); } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 + public void test081() { + this.runConformTest( + new String[] { + "Test.java", + "import static p1.Bar.B;\n" + + "import p3.Foo.*;\n" + + "public class Test {\n" + + " public static void main(String [] args){\n" + + " new Test().beginTest();" + + " }\n" + + " public void beginTest(){\n" + + " System.out.print(\"1 + 1 = \");\n" + + " if(alwaysTrue()) System.out.println(\"2\");\n" + + " else System.out.println(\"3\"); " + + " }\n" + + " public boolean alwaysTrue(){\n" + + " String myB = B.class.getCanonicalName();;\n" + // refers to p1.Bar.B (class) + " String realB = p1.Bar.B.class.getCanonicalName();;\n" + // refers to p1.Bar.B (class) + " B();\n" + // refers to p1.Bar.B() (method) + " return myB.equals(realB);\n" + + " }\n" + + "}\n", + "p1/Bar.java", + "package p1;\n" + + "public class Bar{\n" + + " public static class B{}\n" + + " final public static String B = new String(\"random\");\n" + + " public static void B(){}\n" + + "}\n", + "p3/Foo.java", + "package p3;\n" + + "public class Foo {\n" + + " public class B{\n" + + " public int a;\n" + + " }\n" + + "}\n" + }, + "1 + 1 = 2"); + } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 + public void test082() { + this.runNegativeTest( + new String[] { + "p1/Bar.java", + "package p1;\n" + + "public class Bar{\n" + + " public static class B{}\n" + + " final public static String B = new String(\"random\");\n" + + " public static void B(){}\n" + + "}\n", + "p3/Foo.java", + "package p3;\n" + + "public class Foo {\n" + + " public class B{\n" + + " public int a;\n" + + " }\n" + + "}\n", + "p2/Test.java", + "package p2;\n" + + "import static p1.Bar.B;\n" + + "import p3.Foo.*;\n" + + "public class Test {\n" + + " public static void main(String [] args){\n" + + " new Test().beginTest();" + + " }\n" + + " public void beginTest(){\n" + + " System.out.print(\"1 + 1 = \");\n" + + " if(alwaysTrue()) System.out.println(\"2\");\n" + + " else System.out.println(\"3\"); " + + " }\n" + + " public boolean alwaysTrue(){\n" + + " B b = null;\n" + // refers to p1.Bar.B (class) + " String realB = B;\n" + // refers to p1.Bar.B (field) + " B();\n" + // refers to p1.Bar.B() (method) + " int abc = b.a;\n;" + // static import for Bar.B overshadows on demand import Foo.B + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in p2\\Test.java (at line 15)\n" + + " int abc = b.a;\n" + + " ^\n" + + "a cannot be resolved or is not a field\n" + + "----------\n"); + } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 + public void test083() { + this.runConformTest( + new String[] { + "Test.java", + "import static p1.Bar.B;\n" + + "import p3.Foo.*;\n" + + "public class Test {\n" + + " public static void main(String [] args){\n" + + " new Test().test2();" + + " }\n" + + " public void test2(){\n" + + " System.out.println(B.toString());\n" + // Field obscures class B + " System.out.println(p1.Bar.B.toString());\n" + // Field obscures the class B + " System.out.println(B.class.getCanonicalName().toString());\n" + // the class B + " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + // class B + " }\n" + + "}\n", + "p1/Bar.java", + "package p1;\n" + + "public class Bar{\n" + + " public static class B{}\n" + + " final public static String B = new String(\"random\");\n" + + " public static void B(){}\n" + + "}\n", + "p3/Foo.java", + "package p3;\n" + + "public class Foo {\n" + + " public class B{\n" + + " public int a;\n" + + " }\n" + + "}\n" + }, + "random\n" + + "random\n" + + "p1.Bar.B\n" + + "p1.Bar.B"); + } + + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 + // Check if we're able to find the correct static member type being imported, + // even though the import originally resolved to the static field of the same name, + // coming from the supertype + public void test084() { + this.runConformTest( + new String[] { + "Test.java", + "import static p1.Bar.B;\n" + + "import p3.Foo.*;\n" + + "public class Test {\n" + + " public static void main(String [] args){\n" + + " new Test().test2();" + + " }\n" + + " public void test2(){\n" + + " System.out.println(B.class.getCanonicalName().toString());\n" + // the class B + " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + // class B + " }\n" + + "}\n", + "p1/Bar.java", + "package p1;\n" + + "public class Bar extends SuperBar{\n" + + " public static class B{}\n" + + " public static void B(){}\n" + + "}\n", + "p1/SuperBar.java", + "package p1;\n" + + "public class SuperBar {\n" + + " final public static String B = new String(\"random\");\n" + + "}\n", + "p3/Foo.java", + "package p3;\n" + + "public class Foo {\n" + + " public class B{\n" + + " public int a;\n" + + " }\n" + + "}\n" + }, + "p1.Bar.B\n" + + "p1.Bar.B"); + } + } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java index 78b5aa403..49dced161 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java @@ -758,7 +758,7 @@ public void test023() { "1. ERROR in X.java (at line 6)\n" + " } catch(AX e) {\n" + " ^^\n" + - "Unreachable catch block for AX. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + + "Unreachable catch block for AX. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + "----------\n" + "2. WARNING in X.java (at line 10)\n" + " class AX extends Exception {}\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java index e178b043c..530f636ba 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java @@ -7,18 +7,23 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Stephan Herrmann - Contributions for + * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis + * bug 349326 - [1.7] new warning for missing try-with-resources + * bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; import java.util.Map; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import junit.framework.Test; public class TryWithResourcesStatementTest extends AbstractRegressionTest { static { -// TESTS_NAMES = new String[] { "test055", "test055a" }; +// TESTS_NAMES = new String[] { "test056throw"}; // TESTS_NUMBERS = new int[] { 50 }; // TESTS_RANGE = new int[] { 11, -1 }; } @@ -485,12 +490,17 @@ public void test014() { " ^^\n" + "Dead code\n" + "----------\n" + - "3. ERROR in X.java (at line 5)\n" + + "3. WARNING in X.java (at line 5)\n" + + " Y why = new Y();\n" + + " ^^^\n" + + "Resource leak: 'why' is never closed\n" + + "----------\n" + + "4. ERROR in X.java (at line 5)\n" + " Y why = new Y();\n" + " ^^^^^^^\n" + "Unhandled exception type WeirdException\n" + "----------\n" + - "4. WARNING in X.java (at line 22)\n" + + "5. WARNING in X.java (at line 22)\n" + " class WeirdException extends Throwable {}\n" + " ^^^^^^^^^^^^^^\n" + "The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + @@ -558,12 +568,17 @@ public void test016() { " ^^\n" + "Dead code\n" + "----------\n" + - "3. ERROR in X.java (at line 5)\n" + + "3. WARNING in X.java (at line 5)\n" + + " Y why = new Y();\n" + + " ^^^\n" + + "Resource leak: 'why' is never closed\n" + + "----------\n" + + "4. ERROR in X.java (at line 5)\n" + " Y why = new Y();\n" + " ^^^^^^^\n" + "Unhandled exception type WeirdException\n" + "----------\n" + - "4. WARNING in X.java (at line 20)\n" + + "5. WARNING in X.java (at line 20)\n" + " class WeirdException extends Throwable {}\n" + " ^^^^^^^^^^^^^^\n" + "The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + @@ -3297,6 +3312,57 @@ public void test053() { "Unhandled exception type IOException\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=348705 +// Variant of the above, witness for https://bugs.eclipse.org/358827#c6 +public void test053a() { + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void method1(){\n" + + " try (Y y = new Y()) { \n" + + " y.close();\n" + + " System.out.println();\n" + + " } catch (RuntimeException e) {\n" + + " } finally {\n" + + " System.out.println();\n" + + " }\n" + + " }\n" + + "}\n" + + "class Y implements Managed {\n" + + " public Y() throws CloneNotSupportedException {}\n" + + " public void close () throws ClassNotFoundException, java.io.IOException {\n" + + " }\n" + + "}\n" + + "interface Managed extends AutoCloseable {}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " try (Y y = new Y()) { \n" + + " ^\n" + + "Unhandled exception type ClassNotFoundException thrown by automatic close() invocation on y\n" + + "----------\n" + + "2. ERROR in X.java (at line 3)\n" + + " try (Y y = new Y()) { \n" + + " ^\n" + + "Unhandled exception type IOException thrown by automatic close() invocation on y\n" + + "----------\n" + + "3. ERROR in X.java (at line 3)\n" + + " try (Y y = new Y()) { \n" + + " ^^^^^^^\n" + + "Unhandled exception type CloneNotSupportedException\n" + + "----------\n" + + "4. ERROR in X.java (at line 4)\n" + + " y.close();\n" + + " ^^^^^^^^^\n" + + "Unhandled exception type ClassNotFoundException\n" + + "----------\n" + + "5. ERROR in X.java (at line 4)\n" + + " y.close();\n" + + " ^^^^^^^^^\n" + + "Unhandled exception type IOException\n" + + "----------\n"); +} // https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862 (NPE when union type is used in the resource section.) public void test054() { this.runNegativeTest( @@ -3380,6 +3446,1736 @@ public void test055a() { }, "Done"); } +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses an AutoCloseable without ever closing it. +public void test056() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, 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);\n" + +// not invoking any methods on FileReader, try to avoid necessary call to superclass() in the compiler +// " char[] in = new char[50];\n" + +// " fileReader.read(in);\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " FileReader fileReader = new FileReader(file);\n" + + " ^^^^^^^^^^\n" + + "Resource leak: 'fileReader' is never closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses an AutoCloseable and closes it but not protected by t-w-r nor regular try-finally +public void test056a() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); + 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);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " fileReader.close();\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " new X().foo();\n" + + " } catch (IOException ioex) {\n" + + " System.out.println(\"caught\");\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " FileReader fileReader = new FileReader(file);\n" + + " ^^^^^^^^^^\n" + + "Resource 'fileReader' should be managed by try-with-resource\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses an AutoCloseable and closes it properly in a finally block +public void test056b() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + 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);\n" + + " try {\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " } finally {\n" + + " fileReader.close();\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " new X().foo();\n" + + " } catch (IOException ioex) {\n" + + " System.out.println(\"caught\");\n" + + " }\n" + + " }\n" + + "}\n" + }, + "caught", /*output*/ + null/*classLibs*/, + true/*shouldFlush*/, + null/*vmargs*/, + options, + null/*requestor*/); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses an AutoCloseable properly within try-with-resources. +public void test056c() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, 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" + + " try (FileReader fileReader = new FileReader(file)) {\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " try {\n" + + " new X().foo();\n" + + " } catch (IOException ioex) {\n" + + " System.out.println(\"caught\");\n" + + " }\n" + + " }\n" + + "}\n" + }, + "caught", /*output*/ + null/*classLibs*/, + true/*shouldFlush*/, + null/*vmargs*/, + options, + null/*requestor*/); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses two AutoCloseables (testing independent analysis) +// - one closeable may be unclosed at a conditional return +// - the other is only conditionally closed +public void test056d() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, 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(boolean flag1, boolean flag2) throws IOException {\n" + + " File file = new File(\"somefile\");\n" + + " char[] in = new char[50];\n" + + " FileReader fileReader1 = new FileReader(file);\n" + + " fileReader1.read(in);\n" + + " FileReader fileReader2 = new FileReader(file);\n" + + " fileReader2.read(in);\n" + + " if (flag1) {\n" + + " fileReader2.close();\n" + + " return;\n" + + " } else if (flag2) {\n" + + " fileReader2.close();\n" + + " }\n" + + " fileReader1.close();\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo(false, true);\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 10)\n" + + " FileReader fileReader2 = new FileReader(file);\n" + + " ^^^^^^^^^^^\n" + + "Potential resource leak: 'fileReader2' may not be closed\n" + + "----------\n" + + "2. ERROR in X.java (at line 14)\n" + + " return;\n" + + " ^^^^^^^\n" + + "Resource leak: 'fileReader1' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +//Bug 349326 - [1.7] new warning for missing try-with-resources +//a method uses two AutoCloseables (testing independent analysis) +//- one closeable may be unclosed at a conditional return +//- the other is only conditionally closed +public void test056d_suppress() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); + options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED); + 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(boolean flag1, boolean flag2) throws IOException {\n" + + " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + + " char[] in = new char[50];\n" + + " FileReader fileReader1 = new FileReader(file);\n" + + " fileReader1.read(in);\n" + + " @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" + + " fileReader2.read(in);\n" + + " if (flag1) {\n" + + " fileReader2.close();\n" + + " return; // not suppressed\n" + + " } else if (flag2) {\n" + + " fileReader2.close();\n" + + " }\n" + + " fileReader1.close();\n" + + " }\n" + + " @SuppressWarnings(\"resource\") // useful suppress\n" + + " void bar() throws IOException {\n" + + " File file = new File(\"somefile\");\n" + + " FileReader fileReader = new FileReader(file);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo(false, true);\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 6)\n" + + " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + + " ^^^^^^^^^^\n" + + "Unnecessary @SuppressWarnings(\"resource\")\n" + + "----------\n" + + "2. ERROR in X.java (at line 14)\n" + + " return; // not suppressed\n" + + " ^^^^^^^\n" + + "Resource leak: 'fileReader1' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// one method returns an AutoCleasble, a second method uses this object without ever closing it. +public void test056e() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, 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" + + " FileReader getReader(String filename) throws IOException {\n" + + " File file = new File(\"somefile\");\n" + + " FileReader fileReader = new FileReader(file);\n" + + " return fileReader;\n" + // don't complain here, pass responsibility to caller + " }\n" + + " void foo() throws IOException {\n" + + " FileReader reader = getReader(\"somefile\");\n" + + " char[] in = new char[50];\n" + + " reader.read(in);\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 11)\n" + + " FileReader reader = getReader(\"somefile\");\n" + + " ^^^^^^\n" + + "Resource leak: 'reader' is never closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method explicitly closes its AutoCloseable rather than using t-w-r +public void test056f() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); + options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); + 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 = null;\n" + + " try {\n" + + " fileReader = new FileReader(file);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " } finally {\n" + + " fileReader.close();\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " FileReader fileReader = null;\n" + + " ^^^^^^^^^^\n" + + "Resource 'fileReader' should be managed by try-with-resource\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// an AutoCloseable local is re-assigned +public void test056g() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + 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);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " fileReader = new FileReader(file);\n" + + " fileReader.read(in);\n" + + " fileReader.close();\n" + + " fileReader = null;\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " fileReader = new FileReader(file);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'fileReader' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// an AutoCloseable local is re-assigned after null-assigned +public void test056g2() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + 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);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " fileReader = null;\n" + + " fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here + " fileReader.read(in);\n" + + " fileReader.close();\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " fileReader = null;\n" + + " ^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'fileReader' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// two AutoCloseables at different nesting levels (anonymous local type) +public void test056h() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + 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" + + " final File file = new File(\"somefile\");\n" + + " final FileReader fileReader = new FileReader(file);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " new Runnable() {\n public void run() {\n" + + " try {\n" + + " fileReader.close();\n" + + " FileReader localReader = new FileReader(file);\n" + + " } catch (IOException ex) { /* nop */ }\n" + + " }}.run();\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 7)\n" + + " final FileReader fileReader = new FileReader(file);\n" + + " ^^^^^^^^^^\n" + + "Potential resource leak: 'fileReader' may not be closed\n" + + "----------\n" + + "2. ERROR in X.java (at line 14)\n" + + " FileReader localReader = new FileReader(file);\n" + + " ^^^^^^^^^^^\n" + + "Resource leak: 'localReader' is never closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// three AutoCloseables in different blocks of the same method +public void test056i() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + 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(boolean f1, boolean f2) throws IOException {\n" + + " File file = new File(\"somefile\");\n" + + " if (f1) {\n" + + " FileReader fileReader = new FileReader(file); // err: not closed\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " while (true) {\n" + + " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + + " loopReader.close();" + + " break;\n" + + " }\n" + + " } else {\n" + + " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + + " if (f2)\n" + + " fileReader.close();\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo(true, true);\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " FileReader fileReader = new FileReader(file); // err: not closed\n" + + " ^^^^^^^^^^\n" + + "Resource leak: 'fileReader' is never closed\n" + + "----------\n" + + "2. WARNING in X.java (at line 16)\n" + + " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + + " ^^^^^^^^^^\n" + + "Potential resource leak: 'fileReader' may not be closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// three AutoCloseables in different blocks of the same method +public void test056i2() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + 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(boolean f1, boolean f2) throws IOException {\n" + + " File file = new File(\"somefile\");\n" + + " if (f1) {\n" + + " FileReader fileReader = new FileReader(file); // properly closed\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " while (true) {\n" + + " fileReader.close();\n" + + " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + + " loopReader.close();\n" + + " break;\n" + + " }\n" + + " } else {\n" + + " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + + " if (f2)\n" + + " fileReader.close();\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo(true, true);\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 18)\n" + + " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + + " ^^^^^^^^^^\n" + + "Potential resource leak: 'fileReader' may not be closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses an AutoCloseable without closing it locally but passing as arg to another method +public void test056j() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + 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);\n" + + " read(fileReader);\n" + + " }\n" + + " void read(FileReader reader) { }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " FileReader fileReader = new FileReader(file);\n" + + " ^^^^^^^^^^\n" + + "Potential resource leak: 'fileReader' may not be closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses an AutoCloseable without closing it locally but passing as arg to another method +public void test056jconditional() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + 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(boolean b) throws IOException {\n" + + " File file = new File(\"somefile\");\n" + + " FileReader fileReader = new FileReader(file);\n" + + " synchronized (b ? this : new X()) {\n" + + " new ReadDelegator(fileReader);\n" + + " }\n" + + " }\n" + + " class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo(true);\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " FileReader fileReader = new FileReader(file);\n" + + " ^^^^^^^^^^\n" + + "Potential resource leak: 'fileReader' may not be closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// many locals, some are AutoCloseable. +// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3, +// doing so would create false positives. +public void test056k() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); + options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); + 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" + + " int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" + + " i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" + + " i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" + + " i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" + + " i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" + + " File file = new File(\"somefile\");\n" + + " FileReader ra1 = null, ra2 = null;\n" + + " try {\n" + + " ra1 = new FileReader(file);\n" + + " ra2 = new FileReader(file);\n" + + " FileReader ra3 = new FileReader(file);\n" + + " char[] in = new char[50];\n" + + " ra1.read(in);\n" + + " ra2.read(in);\n" + + " ra3.close();\n" + + " } finally {\n" + + " ra1.close();\n" + + " }\n" + + " int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits + " FileReader rb1 = null, rb2 = null;\n" + + " try {\n" + + " rb1 = new FileReader(file);\n" + + " rb2 = new FileReader(file);\n" + + " FileReader rb3 = new FileReader(file);\n" + + " char[] in = new char[50];\n" + + " rb1.read(in);\n" + + " rb2.read(in);\n" + + " rb3.close();\n" + + " } finally {\n" + + " rb1.close();\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 12)\n" + + " FileReader ra1 = null, ra2 = null;\n" + + " ^^^\n" + + "Resource 'ra1' should be managed by try-with-resource\n" + + "----------\n" + + "2. ERROR in X.java (at line 15)\n" + + " ra2 = new FileReader(file);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'ra2' is never closed\n" + + "----------\n" + + "3. ERROR in X.java (at line 16)\n" + + " FileReader ra3 = new FileReader(file);\n" + + " ^^^\n" + + "Resource 'ra3' should be managed by try-with-resource\n" + + "----------\n" + + "4. ERROR in X.java (at line 25)\n" + + " FileReader rb1 = null, rb2 = null;\n" + + " ^^^\n" + + "Resource 'rb1' should be managed by try-with-resource\n" + + "----------\n" + + "5. ERROR in X.java (at line 28)\n" + + " rb2 = new FileReader(file);\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'rb2' is never closed\n" + + "----------\n" + + "6. ERROR in X.java (at line 29)\n" + + " FileReader rb3 = new FileReader(file);\n" + + " ^^^\n" + + "Resource 'rb3' should be managed by try-with-resource\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// various non-problems +public void test056l() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); + 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" + + " X(FileReader r0) {}\n" + // don't complain against argument + " FileReader getReader() { return null; }\n" + + " void foo(FileReader r1) throws IOException {\n" + + " FileReader fileReader = getReader();\n" + + " if (fileReader == null)\n" + + " return;\n" + // don't complain, resource is actually null + " FileReader r3 = getReader();\n" + + " if (r3 == null)\n" + + " r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null + " try {\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " r1.read(in);\n" + + " } finally {\n" + + " fileReader.close();\n" + + " r3.close();\n" + // the effect of this close() call might be spoiled by exception in fileReader.close() above, but we ignore exception exits in the analysis + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + + " new X(r2).foo(new FileReader(new File(\"notthere\")));\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " FileReader fileReader = getReader();\n" + + " ^^^^^^^^^^\n" + + "Resource 'fileReader' should be managed by try-with-resource\n" + + "----------\n" + + "2. ERROR in X.java (at line 11)\n" + + " FileReader r3 = getReader();\n" + + " ^^\n" + + "Resource 'r3' should be managed by try-with-resource\n" + + "----------\n" + + "3. ERROR in X.java (at line 24)\n" + + " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + + " ^^\n" + + "Potential resource leak: 'r2' may not be closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// nested try with early exit +public void test056m() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + 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() {\n" + + " File file = new File(\"somefile\");" + + " try {\n" + + " FileReader fileReader = new FileReader(file);\n" + + " try {\n" + + " char[] in = new char[50];\n" + + " if (fileReader.read(in)==0)\n" + + " return;\n" + + " } finally {\n" + + " fileReader.close();\n" + + " }\n" + + " } catch (IOException e) {\n" + + " System.out.println(\"caught\");\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "caught", /*output*/ + null/*classLibs*/, + true/*shouldFlush*/, + null/*vmargs*/, + options, + null/*requestor*/); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// nested try should not interfere with earlier analysis. +public void test056n() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "import java.io.File;\n" + + "import java.io.FileReader;\n" + + "import java.io.IOException;\n" + + "import java.io.FileNotFoundException;\n" + + "public class X {\n" + + " void foo(File someFile, char[] buf) throws IOException {\n" + + " FileReader fr1 = new FileReader(someFile);\n" + + " try {\n" + + " fr1.read(buf);\n" + + " } finally {\n" + + " fr1.close();\n" + + " }\n" + + " try {\n" + + " FileReader fr3 = new FileReader(someFile);\n" + + " try {\n" + + " } finally {\n" + + " fr3.close();\n" + + " }\n" + + " } catch (IOException e) {\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " try {\n" + + " new X().foo(new File(\"missing\"), new char[100]);\n" + + " } catch (FileNotFoundException e) {\n" + + " System.out.println(\"caught\");\n" + + " }\n" + + " }\n" + + "}\n" + }, + "caught", /*output*/ + null/*classLibs*/, + true/*shouldFlush*/, + null/*vmargs*/, + options, + null/*requestor*/); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// if close is guarded by null check this should still be recognized as definitely closed +public void test056o() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "import java.io.File;\n" + + "import java.io.FileReader;\n" + + "import java.io.IOException;\n" + + "import java.io.FileNotFoundException;\n" + + "public class X {\n" + + " void foo(File someFile, char[] buf) throws IOException {\n" + + " FileReader fr1 = null;\n" + + " try {\n" + + " fr1 = new FileReader(someFile);" + + " fr1.read(buf);\n" + + " } finally {\n" + + " if (fr1 != null)\n" + + " try {\n" + + " fr1.close();\n" + + " } catch (IOException e) { /*do nothing*/ }\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " try {\n" + + " new X().foo(new File(\"missing\"), new char[100]);\n" + + " } catch (FileNotFoundException e) {\n" + + " System.out.println(\"caught\");\n" + + " }\n" + + " }\n" + + "}\n" + }, + "caught", /*output*/ + null/*classLibs*/, + true/*shouldFlush*/, + null/*vmargs*/, + options, + null/*requestor*/); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// a method uses an AutoCloseable without ever closing it, type from a type variable +public void test056p() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); + options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.File;\n" + + "import java.io.FileReader;\n" + + "import java.io.Reader;\n" + + "import java.io.IOException;\n" + + "public abstract class X <T extends Reader> {\n" + + " void foo() throws IOException {\n" + + " File file = new File(\"somefile\");\n" + + " T fileReader = newReader(file);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " }\n" + + " abstract T newReader(File file) throws IOException;\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X<FileReader>() {\n" + + " FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" + + " }.foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " T fileReader = newReader(file);\n" + + " ^^^^^^^^^^\n" + + "Resource leak: 'fileReader' is never closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// closed in dead code +public void test056q() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + 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);\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " if (2*2 == 4)\n" + + " return;\n" + + " fileReader.close();\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " FileReader fileReader = new FileReader(file);\n" + + " ^^^^^^^^^^\n" + + "Resource leak: 'fileReader' is never closed\n" + + "----------\n" + + "2. WARNING in X.java (at line 10)\n" + + " if (2*2 == 4)\n" + + " ^^^^^^^^\n" + + "Comparing identical expressions\n" + + "----------\n" + + "3. WARNING in X.java (at line 12)\n" + + " fileReader.close();\n" + + " ^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// closed in dead code +public void test056r() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + 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 fr = new FileReader(file);\n" + + " Object b = null;\n" + + " fr.close();\n" + + " if (b != null) {\n" + + " fr = new FileReader(file);\n" + + " return;\n" + + " } else {\n" + + " System.out.print(42);\n" + + " }\n" + + " return; // Should not complain about fr\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " if (b != null) {\n" + + " fr = new FileReader(file);\n" + + " return;\n" + + " } else {\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n" + + "2. WARNING in X.java (at line 13)\n" + + " } else {\n" + + " System.out.print(42);\n" + + " }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation +public void test056s() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); + 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" + + " try (FileReader fileReader = new FileReader(file);) {\n" + + " char[] in = new char[50];\n" + + " fileReader.read(in);\n" + + " fileReader = new FileReader(file); // debug here\n" + + " fileReader.read(in);\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 10)\n" + + " fileReader = new FileReader(file); // debug here\n" + + " ^^^^^^^^^^\n" + + "The resource fileReader of a try-with-resources statement cannot be assigned\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// resource is closed, dead code follows +public void test056t() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "import java.io.IOException;\n" + + "public class X {\n" + + " void foo31() throws IOException {\n" + + " FileReader reader = new FileReader(\"file\"); //warning\n" + + " if (reader != null) {\n" + + " reader.close();\n" + + " } else {\n" + + " // nop\n" + + " }\n" + + " }\n" + + " public static void main(String[] args) throws IOException {\n" + + " new X().foo31();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " } else {\n" + + " // nop\n" + + " }\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Dead code\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// resource is reassigned within t-w-r with different resource +// was initially broken due to https://bugs.eclipse.org/358827 +public void test056u() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo() throws Exception {\n" + + " FileReader reader1 = new FileReader(\"file1\");\n" + + " FileReader reader2 = new FileReader(\"file2\");\n" + + " reader2 = reader1;// this disconnects reader 2\n" + + " try (FileReader reader3 = new FileReader(\"file3\")) {\n" + + " int ch;\n" + + " while ((ch = reader2.read()) != -1) {\n" + + " System.out.println(ch);\n" + + " reader1.read();\n" + + " }\n" + + " reader2 = reader1; // warning 1 regarding original reader1\n" + // this warning was missing + " reader2 = reader1; // warning 2 regarding original reader1\n" + + " } finally {\n" + + " if (reader2 != null) {\n" + + " reader2.close();\n" + + " } else {\n" + + " System.out.println();\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " FileReader reader2 = new FileReader(\"file2\");\n" + + " ^^^^^^^\n" + + "Resource leak: 'reader2' is never closed\n" + + "----------\n" + + "2. ERROR in X.java (at line 13)\n" + + " reader2 = reader1; // warning 1 regarding original reader1\n" + + " ^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'reader1' is not closed at this location\n" + + "----------\n" + + "3. ERROR in X.java (at line 14)\n" + + " reader2 = reader1; // warning 2 regarding original reader1\n" + + " ^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'reader1' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// scope-related pbs reported in https://bugs.eclipse.org/349326#c70 and https://bugs.eclipse.org/349326#c82 +public void test056v() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " boolean foo1() throws Exception {\n" + + " FileReader reader = new FileReader(\"file\");\n" + + " try {\n" + + " int ch;\n" + + " while ((ch = reader.read()) != -1) {\n" + + " System.out.println(ch);\n" + + " reader.read();\n" + + " }\n" + + " if (ch > 10) {\n" + + " return true;\n" + + " }\n" + + " return false;\n" + // return while resource from enclosing scope remains unclosed + " } finally {\n" + + " }\n" + + " }\n" + + " void foo111() throws Exception {\n" + + " FileReader reader111 = new FileReader(\"file2\");\n" + + " try {\n" + + " int ch;\n" + + " while ((ch = reader111.read()) != -1) {\n" + + " System.out.println(ch);\n" + + " reader111.read();\n" + + " }\n" + + " return;\n" + // this shouldn't spoil the warning "should be managed with t-w-r" + " } finally {\n" + + " if (reader111 != null) {\n" + + " reader111.close();\n" + + " }\n" + + " }\n" + + " }\n" + + " void foo2() throws Exception {\n" + + " FileReader reader2 = new FileReader(\"file\");\n" + + " try {\n" + + " int ch;\n" + + " while ((ch = reader2.read()) != -1) {\n" + + " System.out.println(ch);\n" + + " reader2.read();\n" + + " }\n" + + " if (ch > 10) {\n" + + " return;\n" + // potential leak + " }\n" + + " } finally {\n" + + " }\n" + + " reader2.close();\n" + // due to this close we don't say "never closed" + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " FileReader reader = new FileReader(\"file\");\n" + + " ^^^^^^\n" + + "Resource leak: 'reader' is never closed\n" + + "----------\n" + + "2. WARNING in X.java (at line 19)\n" + + " FileReader reader111 = new FileReader(\"file2\");\n" + + " ^^^^^^^^^\n" + + "Resource 'reader111' should be managed by try-with-resource\n" + + "----------\n" + + "3. ERROR in X.java (at line 42)\n" + + " return;\n" + + " ^^^^^^^\n" + + "Resource leak: 'reader2' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// end of method is dead end, but before we have both a close() and an early return +public void test056w() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " boolean foo1() throws Exception {\n" + + " FileReader reader = new FileReader(\"file\");\n" + + " try {\n" + + " int ch;\n" + + " while ((ch = reader.read()) != -1) {\n" + + " System.out.println(ch);\n" + + " reader.read();\n" + + " }\n" + + " if (ch > 10) {\n" + + " reader.close();\n" + + " return true;\n" + + " }\n" + + " return false;\n" + + " } finally {\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 15)\n" + + " return false;\n" + + " ^^^^^^^^^^^^^\n" + + "Resource leak: 'reader' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// different early exits, if no close seen report as definitely unclosed +public void test056x() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo31(boolean b) throws Exception {\n" + + " FileReader reader = new FileReader(\"file\");\n" + + " if (b) {\n" + + " reader.close();\n" + + " } else {\n" + + " return; // warning\n" + + " }\n" + + " }\n" + + " void foo32(boolean b) throws Exception {\n" + + " FileReader reader = new FileReader(\"file\"); // warn here\n" + + " return;\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " return; // warning\n" + + " ^^^^^^^\n" + + "Resource leak: 'reader' is not closed at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 12)\n" + + " FileReader reader = new FileReader(\"file\"); // warn here\n" + + " ^^^^^^\n" + + "Resource leak: 'reader' is never closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// nested method passes the resource to outside code +public void test056y() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo31(boolean b) throws Exception {\n" + + " final FileReader reader31 = new FileReader(\"file\");\n" + + " new Runnable() {\n" + + " public void run() {\n" + + " foo18(reader31);\n" + + " }\n" + + " }.run();\n" + + " }\n" + + " void foo18(FileReader r18) {\n" + + " // could theoretically close r18;\n" + + " }\n" + + " abstract class ResourceProvider {\n" + + " abstract FileReader provide();" + + " }\n" + + " ResourceProvider provider;" + + " void foo23() throws Exception {\n" + + " final FileReader reader23 = new FileReader(\"file\");\n" + + " provider = new ResourceProvider() {\n" + + " public FileReader provide() {\n" + + " return reader23;\n" + + " }\n" + + " };\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in X.java (at line 4)\n" + + " final FileReader reader31 = new FileReader(\"file\");\n" + + " ^^^^^^^^\n" + + "Potential resource leak: 'reader31' may not be closed\n" + + "----------\n" + + "2. WARNING in X.java (at line 17)\n" + + " final FileReader reader23 = new FileReader(\"file\");\n" + + " ^^^^^^^^\n" + + "Potential resource leak: 'reader23' may not be closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// resource assigned to second local and is (potentially) closed on the latter +public void test056z() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo17() throws Exception {\n" + + " FileReader reader17 = new FileReader(\"file\");\n" + + " final FileReader readerCopy = reader17;\n" + + " readerCopy.close();\n" + + " }\n" + + " void foo17a() throws Exception {\n" + + " FileReader reader17a = new FileReader(\"file\");\n" + + " FileReader readerCopya;" + + " readerCopya = reader17a;\n" + + " bar(readerCopya);\n" + // potentially closes + " }\n" + + " void bar(FileReader r) {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 9)\n" + + " FileReader reader17a = new FileReader(\"file\");\n" + + " ^^^^^^^^^\n" + + "Potential resource leak: 'reader17a' may not be closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// multiple early exists from nested scopes (always closed) +public void test056zz() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo16() throws Exception {\n" + + " FileReader reader16 = new FileReader(\"file\");\n" + + " try {\n" + + " reader16.close();\n " + + " return;\n" + + " } catch (RuntimeException re) {\n" + + " return;\n" + + " } catch (Error e) {\n" + + " return;\n" + + " } finally {\n" + + " reader16.close();\n " + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " FileReader reader16 = new FileReader(\"file\");\n" + + " ^^^^^^^^\n" + + "Resource 'reader16' should be managed by try-with-resource\n" + + "----------\n", + null, + true, + options); +} +// Bug 349326 - [1.7] new warning for missing try-with-resources +// multiple early exists from nested scopes (never closed) +public void test056zzz() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo16() throws Exception {\n" + + " FileReader reader16 = new FileReader(\"file\");\n" + + " try {\n" + + " return;\n" + + " } catch (RuntimeException re) {\n" + + " return;\n" + + " } catch (Error e) {\n" + + " return;\n" + + " } finally {\n" + + " System.out.println();\n " + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " FileReader reader16 = new FileReader(\"file\");\n" + + " ^^^^^^^^\n" + + "Resource leak: 'reader16' is never closed\n" + + "----------\n", + null, + true, + options); +} +// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points +// explicit throw is a true method exit here +public void test056throw1() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo2(boolean a, boolean b, boolean c) throws Exception {\n" + + " FileReader reader = new FileReader(\"file\");\n" + + " if(a)\n" + + " throw new Exception(); //warning 1\n" + + " else if (b)\n" + + " reader.close();\n" + + " else if(c)\n" + + " throw new Exception(); //warning 2\n" + + " reader.close();\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " throw new Exception(); //warning 1\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'reader' is not closed at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 10)\n" + + " throw new Exception(); //warning 2\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Resource leak: 'reader' is not closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points +// close() within finally provides protection for throw +public void test056throw2() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo1() throws Exception {\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " try {\n" + + " reader.read();\n" + + " return;\n" + + " } catch (Exception e) {\n" + + " throw new Exception();\n" + + " } finally {\n" + + " reader.close();\n" + + " }\n" + + " }\n" + + "\n" + + " void foo2() throws Exception {\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " try {\n" + + " reader.read();\n" + + " throw new Exception(); // should not warn here\n" + + " } catch (Exception e) {\n" + + " throw new Exception();\n" + + " } finally {\n" + + " reader.close();\n" + + " }\n" + + " }\n" + + "\n" + + " void foo3() throws Exception {\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " try {\n" + + " reader.read();\n" + + " throw new Exception();\n" + + " } finally {\n" + + " reader.close();\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " ^^^^^^\n" + + "Resource 'reader' should be managed by try-with-resource\n" + + "----------\n" + + "2. ERROR in X.java (at line 16)\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " ^^^^^^\n" + + "Resource 'reader' should be managed by try-with-resource\n" + + "----------\n" + + "3. ERROR in X.java (at line 28)\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " ^^^^^^\n" + + "Resource 'reader' should be managed by try-with-resource\n" + + "----------\n", + null, + true, + options); +} +// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points +// close() nested within finally provides protection for throw +public void test056throw3() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo2x() throws Exception {\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " try {\n" + + " reader.read();\n" + + " throw new Exception(); // should not warn here\n" + + " } catch (Exception e) {\n" + + " throw new Exception();\n" + + " } finally {\n" + + " if (reader != null)\n" + + " try {\n" + + " reader.close();\n" + + " } catch (java.io.IOException io) {}\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + + " ^^^^^^\n" + + "Resource 'reader' should be managed by try-with-resource\n" + + "----------\n", + null, + true, + options); +} +// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points +// additional boolean should shed doubt on whether we reach the close() call +public void test056throw4() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo2x(boolean b) throws Exception {\n" + + " FileReader reader = new FileReader(\"file\");\n" + + " try {\n" + + " reader.read();\n" + + " throw new Exception(); // should warn here\n" + + " } catch (Exception e) {\n" + + " throw new Exception(); // should warn here\n" + + " } finally {\n" + + " if (reader != null && b)\n" + // this condition is too strong to protect reader + " try {\n" + + " reader.close();\n" + + " } catch (java.io.IOException io) {}\n" + + " }\n" + + " }\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " throw new Exception(); // should warn here\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential resource leak: 'reader' may not be closed at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 9)\n" + + " throw new Exception(); // should warn here\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential resource leak: 'reader' may not be closed at this location\n" + + "----------\n", + null, + true, + options); +} +// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points +// similar to test056throw3() but indirectly calling close(), so doubts remain. +public void test056throw5() { + Map options = getCompilerOptions(); + options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); + options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "import java.io.FileReader;\n" + + "public class X {\n" + + " void foo2x() throws Exception {\n" + + " FileReader reader = new FileReader(\"file\");\n" + + " try {\n" + + " reader.read();\n" + + " throw new Exception(); // should warn 'may not' here\n" + + " } catch (Exception e) {\n" + + " throw new Exception(); // should warn 'may not' here\n" + + " } finally {\n" + + " doClose(reader);\n" + + " }\n" + + " }\n" + + " void doClose(FileReader r) { try { r.close(); } catch (java.io.IOException ex) {}}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 7)\n" + + " throw new Exception(); // should warn \'may not\' here\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential resource leak: 'reader' may not be closed at this location\n" + + "----------\n" + + "2. ERROR in X.java (at line 9)\n" + + " throw new Exception(); // should warn \'may not\' here\n" + + " ^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential resource leak: 'reader' may not be closed at this location\n" + + "----------\n", + null, + true, + options); +} public static Class testClass() { return TryWithResourcesStatementTest.class; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java index 773fd4835..f62b0ed0e 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -348,7 +348,7 @@ private String getVerifyTestsCode() { " this.socket.setTcpNoDelay(true);\n" + " server.close();\n" + "\n" + - " DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" + + " final DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" + " final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());\n" + " while (true) {\n" + " final String className = in.readUTF();\n" + |