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 ?