Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2019-12-25 21:52:01 +0000
committerStephan Herrmann2019-12-25 22:18:45 +0000
commit956124562eb3b9e814a13212d1ed4c2577a40178 (patch)
tree09352b5d50a8a38d189029e410ff7a2c4a1b01ee
parentabfd074d566b02cad792fdd003f292c2ebd53ad0 (diff)
downloadeclipse.jdt.core-956124562eb3b9e814a13212d1ed4c2577a40178.tar.gz
eclipse.jdt.core-956124562eb3b9e814a13212d1ed4c2577a40178.tar.xz
eclipse.jdt.core-956124562eb3b9e814a13212d1ed4c2577a40178.zip
Bug 552521 - [resource] warning against '<unassigned Closeable value>'
is weakened to "potential" inside "if" Change-Id: I79f6397e6a1e022a90c6272008d6cd667f25599f
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java156
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java7
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java13
3 files changed, 174 insertions, 2 deletions
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 232019db46..e044f14439 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
@@ -5849,4 +5849,160 @@ public void testBug463320_comment19() {
},
options);
}
+public void testBug552521() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses try-with-resources
+
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING);
+ runLeakTest(
+ new String[] {
+ "EclipseBug552521getChannel.java",
+ "import java.io.File;\n" +
+ "import java.io.FileInputStream;\n" +
+ "import java.io.FileOutputStream;\n" +
+ "import java.nio.channels.FileChannel;\n" +
+ "\n" +
+ "public class EclipseBug552521getChannel {\n" +
+ "\n" +
+ " @SuppressWarnings(\"unused\")\n" +
+ " public void copyFile(final File srcFile, final File dstFile) throws Exception {\n" +
+ " /*\n" +
+ " * TODO Eclipse Setting: Window/Preferences/Java/Compiler/Errors-Warnings/\n" +
+ " * Resource not managed via try-with-resource = Ignore (default)\n" +
+ " */\n" +
+ " try (\n" +
+ " final FileInputStream srcStream = new FileInputStream (srcFile);\n" +
+ " final FileChannel srcChannel = srcStream.getChannel();\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 17
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO Warning ok\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ "\n" +
+ " if (srcFile.isFile()) { // \"if\" (resolved at runtime) -> Warning suppressed\n" +
+ " try (\n" +
+ " final FileInputStream srcStream = new FileInputStream (srcFile);\n" +
+ " final FileChannel srcChannel = srcStream.getChannel();\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 28
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIXME Warning missing!\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ " } else { // \"else\" (resolved at runtime) -> Warning suppressed\n" +
+ " try (\n" +
+ " final FileInputStream srcStream = new FileInputStream (srcFile);\n" +
+ " final FileChannel srcChannel = srcStream.getChannel();\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 38
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIXME Warning missing!\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " if (true) { // Dummy \"if\" (= constant true) -> Warning\n" +
+ " try (\n" +
+ " final FileInputStream srcStream = new FileInputStream (srcFile);\n" +
+ " final FileChannel srcChannel = srcStream.getChannel();\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 50
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO Warning ok\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ " } else { // Dummy \"else\" (= constant false) -> Warning suppressed\n" +
+ " try (\n" +
+ " final FileInputStream srcStream = new FileInputStream (srcFile);\n" +
+ " final FileChannel srcChannel = srcStream.getChannel();\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 60
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIXME Warning missing!\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " if (false) { // Dummy \"if\" (= constant false) -> Warning suppressed\n" +
+ " try (\n" +
+ " final FileInputStream srcStream = new FileInputStream (srcFile);\n" +
+ " final FileChannel srcChannel = srcStream.getChannel();\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 72
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIXME Warning missing!\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ " } else { // Dummy \"else\" (= constant true) -> Warning\n" +
+ " try (\n" +
+ " final FileInputStream srcStream = new FileInputStream (srcFile);\n" +
+ " final FileChannel srcChannel = srcStream.getChannel();\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" + // line 82
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO Warning ok\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ " }\n" +
+ " /*\n" +
+ " * Following test-case differs from all the above as follows:\n" +
+ " * FileInputStream is unassigned, instead of FileOutputStream\n" +
+ " */\n" +
+ " try (\n" +
+ " final FileChannel srcChannel = new FileInputStream (srcFile) .getChannel();\n" + // line 94
+ " // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO Warning ok\n" +
+ " final FileOutputStream dstStream = new FileOutputStream(srcFile);\n" +
+ " final FileChannel dstChannel = dstStream.getChannel();\n" +
+ " )\n" +
+ " {\n" +
+ " srcChannel.transferTo(0, srcChannel.size(), dstChannel);\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in EclipseBug552521getChannel.java (at line 17)\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "2. ERROR in EclipseBug552521getChannel.java (at line 28)\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "3. ERROR in EclipseBug552521getChannel.java (at line 38)\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "4. ERROR in EclipseBug552521getChannel.java (at line 50)\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "5. ERROR in EclipseBug552521getChannel.java (at line 60)\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "6. ERROR in EclipseBug552521getChannel.java (at line 72)\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "7. ERROR in EclipseBug552521getChannel.java (at line 82)\n" +
+ " final FileChannel dstChannel = new FileOutputStream(dstFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n" +
+ "8. ERROR in EclipseBug552521getChannel.java (at line 94)\n" +
+ " final FileChannel srcChannel = new FileInputStream (srcFile) .getChannel();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" +
+ "----------\n",
+ options);
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index 1ffed5baae..9bb4aa893e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -790,8 +790,13 @@ public class FakedTrackingVariable extends LocalDeclaration {
if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
return FlowInfo.POTENTIALLY_NULL; // non-null + doubt = pot null
return FlowInfo.NON_NULL;
- } else if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
+ } else if ((status & FlowInfo.POTENTIALLY_NULL) != 0) {
return FlowInfo.POTENTIALLY_NULL;
+ } else if (status == FlowInfo.UNKNOWN) {
+ // if unassigned resource (not having an originalBinding) is not withdrawn it is unclosed:
+ if (this.originalBinding == null)
+ return FlowInfo.NULL;
+ }
return status;
}
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 bf4ea57df6..a21beb4742 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
@@ -1167,8 +1167,19 @@ public void correlateTrackingVarsIfElse(FlowInfo thenFlowInfo, FlowInfo elseFlow
int trackVarCount = this.trackingVariables.size();
for (int i=0; i<trackVarCount; i++) {
FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
- if (trackingVar.originalBinding == null)
+ if (trackingVar.originalBinding == null) {
+ // avoid problem weakened to 'potential' if unassigned resource exists only in one branch:
+ boolean hasNullInfoInThen = thenFlowInfo.hasNullInfoFor(trackingVar.binding);
+ boolean hasNullInfoInElse = elseFlowInfo.hasNullInfoFor(trackingVar.binding);
+ if (hasNullInfoInThen && !hasNullInfoInElse) {
+ int nullStatus = thenFlowInfo.nullStatus(trackingVar.binding);
+ elseFlowInfo.markNullStatus(trackingVar.binding, nullStatus);
+ } else if (!hasNullInfoInThen && hasNullInfoInElse) {
+ int nullStatus = elseFlowInfo.nullStatus(trackingVar.binding);
+ thenFlowInfo.markNullStatus(trackingVar.binding, nullStatus);
+ }
continue;
+ }
if ( thenFlowInfo.isDefinitelyNonNull(trackingVar.binding) // closed in then branch
&& elseFlowInfo.isDefinitelyNull(trackingVar.originalBinding)) // null in else branch
{

Back to the top