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 9052e4e..7fa03cb 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 @@ -26,7 +26,7 @@ import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; public class ResourceLeakTests extends AbstractRegressionTest { static { -// TESTS_NAMES = new String[] { "test061l"}; + TESTS_NAMES = new String[] { "testBug368709b"}; // TESTS_NUMBERS = new int[] { 50 }; // TESTS_RANGE = new int[] { 11, -1 }; } @@ -3085,5 +3085,88 @@ public void test063e() { options, null); } - +// Bug 368709 - Endless loop in FakedTrackingVariable.markPassedToOutside +// original test case from jgit +public void testBug368709a() { + if (this.complianceLevel < ClassFileConstants.JDK1_5) return; + 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.*;\n" + + "import java.util.zip.*;\n" + + "public class X {\n" + + " Object db, pack;\n" + // mock + " int objectOffset, headerLength, type, size;\n" + + " public ObjectStream openStream() throws MissingObjectException, IOException {\n" + + " WindowCursor wc = new WindowCursor(db);\n" + + " InputStream in;\n" + + " try\n" + + " {\n" + + " in = new PackInputStream(pack, (objectOffset + headerLength), wc);\n" + + " }\n" + + " catch (IOException packGone)\n" + + " {\n" + + " return wc.open(getObjectId(), type).openStream();\n" + + " }\n" + + " in = new BufferedInputStream(new InflaterInputStream(in, wc.inflater(), 8192), 8192);\n" + + " return new ObjectStream.Filter(type, size, in);\n" + + " }\n" + + " String getObjectId() { return \"\"; }\n" + // mock + "}\n" + + // mock: + "class WindowCursor {\n" + + " WindowCursor(Object db) {}\n" + + " ObjectStream open(String id, int type) { return null; }\n" + + " Inflater inflater() { return null; }\n" + + "}\n" + + "class MissingObjectException extends Exception { MissingObjectException() { super();} }\n" + + "class PackInputStream extends InputStream {\n" + + " PackInputStream(Object pack, int offset, WindowCursor wc) {}\n" + + "}\n" + + "class ObjectStream extends InputStream {\n" + + " static class Filter extends ObjectStream {\n" + + " Filter(int type, int size, InputStream in) { }\n" + + " }\n" + + " ObjectStream openStream() { return this; }\n" + + "}\n" + }, + "", + null, + true, + null, + options, + null); +} +//Bug 368709 - Endless loop in FakedTrackingVariable.markPassedToOutside +//original test case from jgit +public void testBug368709b() { + if (this.complianceLevel < ClassFileConstants.JDK1_5) return; + 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.*;\n" + + "import java.util.zip.*;\n" + + "public class X {\n" + + " void doit() throws IOException {\n" + + " InputStream in = new FileInputStream(\"somefile\");\n" + + " in = new BufferedInputStream(new InflaterInputStream(in, inflater(), 8192), 8192);\n" + + " process(in);\n" + + " }\n" + + " Inflater inflater() { return null; }\n" + + " void process(InputStream is) { }\n" + + "}\n" + }, + "", + null, + true, + null, + options, + null); +} } 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 46ac85d..7101ef7 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 @@ -209,8 +209,12 @@ public class FakedTrackingVariable extends LocalDeclaration { // find the wrapped resource represented by its tracking var: FakedTrackingVariable innerTracker = findCloseTracker(scope, flowInfo, allocation.arguments[0]); if (innerTracker != null) { - if (innerTracker == allocation.closeTracker) - return; // self wrap (res = new Res(res)) -> neither change (here) nor remove (below) + FakedTrackingVariable currentInner = innerTracker; + while (currentInner != null) { + if (currentInner == allocation.closeTracker) + return; // self wrap (res = new Res(res)) -> neither change (here) nor remove (below) + currentInner = currentInner.innerTracker; + } int newStatus = FlowInfo.NULL; if (allocation.closeTracker == null) { allocation.closeTracker = new FakedTrackingVariable(scope, allocation); // no local available, closeable is unassigned