Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSatyam Kandula2012-05-23 13:15:35 +0000
committerSatyam Kandula2012-05-23 13:15:35 +0000
commit90457871ba3051d340feae7220f15bab37c7d551 (patch)
tree5dec188e20420cc7cd0dca92d80675c8ffa0e825
parent7ca9f198dab5ae249453376b5f6d99317f797266 (diff)
downloadeclipse.jdt.core-90457871ba3051d340feae7220f15bab37c7d551.tar.gz
eclipse.jdt.core-90457871ba3051d340feae7220f15bab37c7d551.tar.xz
eclipse.jdt.core-90457871ba3051d340feae7220f15bab37c7d551.zip
Fix for bug 380112: [1.7][compiler] Incorrect unreachable catch blockv20120523-1315
detection in try-with-resources
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java116
-rw-r--r--org.eclipse.jdt.core.tests.compiler/workspace/Test380112.jarbin0 -> 1258 bytes
-rw-r--r--org.eclipse.jdt.core/buildnotes_jdt-core.html4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java48
4 files changed, 160 insertions, 8 deletions
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 e606150ea4..43a7fa40a1 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
@@ -14,6 +14,7 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
+import java.io.File;
import java.util.Map;
import junit.framework.Test;
@@ -22,7 +23,7 @@ import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
public class TryWithResourcesStatementTest extends AbstractRegressionTest {
static {
-// TESTS_NAMES = new String[] { "test061m"};
+// TESTS_NAMES = new String[] { "test380112e"};
// TESTS_NUMBERS = new int[] { 50 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -4078,6 +4079,119 @@ public void test375326g() {
"The local variable a may not have been initialized\n" +
"----------\n");
}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+public void test380112a() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "interface I extends Closeable, Serializable {}\n" +
+ "public class X {\n"+
+ " public static void main(String [] args) {\n" +
+ " try (I i = getX()) {\n" +
+ " } catch (IOException x) {\n" +
+ " }\n"+
+ " System.out.println(\"Done\");\n" +
+ " }\n" +
+ " public static I getX() { return null;}\n"+
+ " public X(){}\n" +
+ "}\n"
+ },
+ "Done");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+//variant with finally
+public void test380112b() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "interface I extends Closeable, Serializable {}\n" +
+ "public class X {\n"+
+ " public static void main(String [] args) {\n" +
+ " try (I i = getX()) {\n" +
+ " } catch (IOException x) {\n" +
+ " } finally {\n"+
+ " System.out.println(\"Done\");\n" +
+ " }\n" +
+ " }\n" +
+ " public static I getX() { return null;}\n"+
+ " public X(){}\n" +
+ "}\n"
+ },
+ "Done");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+//variant with two methods throwing different Exceptions (one subtype of other)
+//subtype should be the one to be caught
+public void test380112c() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "interface I2 { public void close() throws FileNotFoundException; }\n"+
+ "interface I extends Closeable, I2 {}\n" +
+ "public class X {\n"+
+ " public static void main(String [] args) {\n" +
+ " try (I i = getX()) {\n" +
+ " } catch (FileNotFoundException x) {\n" +
+ " }\n"+
+ " System.out.println(\"Done\");\n" +
+ " }\n" +
+ " public static I getX() { return null;}\n"+
+ " public X(){}\n" +
+ "}\n"
+ },
+ "Done");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+//test380112c's variant with finally
+public void test380112d() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "interface I2 { public void close() throws FileNotFoundException; }\n"+
+ "interface I extends Closeable, I2 {}\n" +
+ "public class X {\n"+
+ " public static void main(String [] args) {\n" +
+ " try (I i = getX()) {\n" +
+ " } catch (FileNotFoundException x) {\n" +
+ " } finally {\n"+
+ " System.out.println(\"Done\");\n" +
+ " }\n" +
+ " }\n" +
+ " public static I getX() { return null;}\n"+
+ " public X(){}\n" +
+ "}\n"
+ },
+ "Done");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+//test380112a variant moving the Interface into a binary
+public void test380112e() {
+ String path = this.getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator + "Test380112.jar";
+ String[] defaultLibs = getDefaultClassPaths();
+ String[] libs = new String[defaultLibs.length + 1];
+ System.arraycopy(defaultLibs, 0, libs, 0, defaultLibs.length);
+ libs[defaultLibs.length] = path;
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "import pkg380112.I;\n" +
+ "public class X {\n"+
+ " public static void main(String [] args) {\n" +
+ " try (I i = getX()) {\n" +
+ " } catch (IOException x) {\n" +
+ " }\n"+
+ " System.out.println(\"Done\");\n" +
+ " }\n" +
+ " public static I getX() { return null;}\n"+
+ " public X(){}\n" +
+ "}\n"
+ }, "Done", libs, true, new String[] {"-cp", path});
+}
public static Class testClass() {
return TryWithResourcesStatementTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/workspace/Test380112.jar b/org.eclipse.jdt.core.tests.compiler/workspace/Test380112.jar
new file mode 100644
index 0000000000..856a7110ce
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/workspace/Test380112.jar
Binary files differ
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index c0ed8fdb68..a101ce8a16 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -52,7 +52,9 @@ Eclipse SDK 3.8.0 - %date% - 3.8.0
<h2>What's new in this drop</h2>
<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=379726">379726</a>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112">380112</a>
+[1.7][compiler] Incorrect unreachable catch block detection in try-with-resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=379726">379726</a>
Include Eclipse-BundleShape in test plugin MANIFEST.MF
<a name="v_C55"></a>
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 01291ad0f4..68fa1c1597 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
@@ -129,9 +129,10 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
FlowInfo tryInfo = flowInfo.copy();
for (int i = 0; i < resourcesLength; i++) {
- tryInfo = this.resources[i].analyseCode(currentScope, handlingContext, tryInfo);
+ final LocalDeclaration resource = this.resources[i];
+ tryInfo = resource.analyseCode(currentScope, handlingContext, tryInfo);
this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(tryInfo);
- LocalVariableBinding resourceBinding = this.resources[i].binding;
+ LocalVariableBinding resourceBinding = resource.binding;
resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
if (resourceBinding.closeTracker != null) {
// this was false alarm, we don't need to track the resource
@@ -142,7 +143,24 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
if (type != null && type.isValidBinding()) {
ReferenceBinding binding = (ReferenceBinding) type;
MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
- if (closeMethod != null && closeMethod.returnType.id == TypeIds.T_void) {
+ if(closeMethod == null) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+ // closeMethod could be null if the binding is from an interface
+ // extending from multiple interfaces.
+ InvocationSite site = new InvocationSite() {
+ public TypeBinding[] genericTypeArguments() { return null;}
+ public boolean isSuperAccess() {return false;}
+ public boolean isTypeAccess() {return false;}
+ public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
+ public void setDepth(int depth) {/* empty */ }
+ public void setFieldIndex(int depth) {/* empty */ }
+ public int sourceEnd() {return resource.sourceEnd(); }
+ public int sourceStart() {return resource.sourceStart(); }
+ public TypeBinding expectedType() { return null; }
+ };
+ closeMethod = this.scope.compilationUnitScope().findMethod(binding, ConstantPool.Close, new TypeBinding[0], site, false);
+ }
+ if (closeMethod != null && closeMethod.isValidBinding() && closeMethod.returnType.id == TypeIds.T_void) {
ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions;
for (int j = 0, length = thrownExceptions.length; j < length; j++) {
handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[i], tryInfo, currentScope, true);
@@ -269,9 +287,10 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
FlowInfo tryInfo = flowInfo.copy();
for (int i = 0; i < resourcesLength; i++) {
- tryInfo = this.resources[i].analyseCode(currentScope, handlingContext, tryInfo);
+ final LocalDeclaration resource = this.resources[i];
+ tryInfo = resource.analyseCode(currentScope, handlingContext, tryInfo);
this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(tryInfo);
- LocalVariableBinding resourceBinding = this.resources[i].binding;
+ LocalVariableBinding resourceBinding = resource.binding;
resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
if (resourceBinding.closeTracker != null) {
// this was false alarm, we don't need to track the resource
@@ -282,7 +301,24 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
if (type != null && type.isValidBinding()) {
ReferenceBinding binding = (ReferenceBinding) type;
MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
- if (closeMethod != null && closeMethod.returnType.id == TypeIds.T_void) {
+ if(closeMethod == null) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+ // closeMethod could be null if the binding is from an interface
+ // extending from multiple interfaces.
+ InvocationSite site = new InvocationSite() {
+ public TypeBinding[] genericTypeArguments() { return null;}
+ public boolean isSuperAccess() {return false;}
+ public boolean isTypeAccess() {return false;}
+ public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
+ public void setDepth(int depth) {/* empty */ }
+ public void setFieldIndex(int depth) {/* empty */ }
+ public int sourceEnd() {return resource.sourceEnd(); }
+ public int sourceStart() {return resource.sourceStart(); }
+ public TypeBinding expectedType() { return null; }
+ };
+ closeMethod = this.scope.compilationUnitScope().findMethod(binding, ConstantPool.Close, new TypeBinding[0], site, false);
+ }
+ if (closeMethod != null && closeMethod.isValidBinding() && closeMethod.returnType.id == TypeIds.T_void) {
ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions;
for (int j = 0, length = thrownExceptions.length; j < length; j++) {
handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[i], tryInfo, currentScope, true);

Back to the top