Bug 560733 - Missing warning of unused variables in try-with-resources
declaration
Change-Id: I3273d4ada2d9321dde9b1bf22b692d571eeee1a2
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index 4b05f8d..04909a7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -6486,6 +6486,7 @@
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING);
runConformTest(
new String[] {
"X.java",
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 83620d7..55117b7 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2018 IBM Corporation and others.
+ * Copyright (c) 2011, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -4320,6 +4320,31 @@
" at Test.main(Test.java:14)\n",
null);
}
+public void testBug560733() {
+ Runner runner = new Runner();
+ Map<String, String> options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING);
+ runner.customOptions = options;
+ runner.testFiles = new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "public class X {\n" +
+ " void method() throws IOException {\n" +
+ " try(InputStream in = getClass().getResourceAsStream(\"file\")) {\n" +
+ " System.out.println(\"in is never used.\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ };
+ runner.expectedCompilerLog =
+ "----------\n" +
+ "1. WARNING in X.java (at line 4)\n" +
+ " try(InputStream in = getClass().getResourceAsStream(\"file\")) {\n" +
+ " ^^\n" +
+ "The value of the local variable in is not used\n" +
+ "----------\n";
+ runner.runWarningTest();
+}
public static Class testClass() {
return TryWithResourcesStatementTest.class;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 856c6f6..8e145e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -163,7 +163,7 @@
resolvedType = ((Expression) resource).resolvedType;
}
if (localVariableBinding != null) {
- localVariableBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
+ localVariableBinding.useFlag = LocalVariableBinding.FAKE_USED; // Is implicitly used anyways (technically -- may still be "unneeded")
if (localVariableBinding.closeTracker != null) {
// this was false alarm, we don't need to track the resource
localVariableBinding.closeTracker.withdraw();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index a778679..24c25f4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -251,7 +251,7 @@
// check if variable is actually used, and may force it to be preserved
boolean generateCurrentLocalVar = (local.useFlag > LocalVariableBinding.UNUSED && local.constant() == Constant.NotAConstant);
- // do not report fake used variable
+ // do not report most fake used variable
if (local.useFlag == LocalVariableBinding.UNUSED
&& (local.declaration != null) // unused (and non secret) local
&& ((local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0)) { // declaration is reachable
@@ -262,6 +262,8 @@
else {
problemReporter().unusedLocalVariable(local.declaration);
}
+ } else if (local.useFlag == LocalVariableBinding.FAKE_USED && (local.tagBits & TagBits.IsResource) != 0) {
+ problemReporter().unusedLocalVariable(local.declaration);
}
// could be optimized out, but does need to preserve unread variables ?