aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2012-09-15 14:47:24 (EDT)
committerJayaprakash Arthanareeswaran2012-10-19 00:48:57 (EDT)
commit468885f284e85bd93211c3e5598f6cfedb939993 (patch)
treeaf96d022cd1692cc77bedbe76ff0d529447263fe
parent358064871a7be19bb66d5146eba4dc39b386d385 (diff)
downloadeclipse.jdt.core-468885f284e85bd93211c3e5598f6cfedb939993.zip
eclipse.jdt.core-468885f284e85bd93211c3e5598f6cfedb939993.tar.gz
eclipse.jdt.core-468885f284e85bd93211c3e5598f6cfedb939993.tar.bz2
Bug 387612 - Unreachable catch block...exception is never thrown from
the try
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java138
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java44
2 files changed, 178 insertions, 4 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
index 3fff7df..bcef02a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java
@@ -9,6 +9,7 @@
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contribution for
* bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ * bug 387612 - Unreachable catch block...exception is never thrown from the try
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -25,7 +26,7 @@ import junit.framework.Test;
public class TryStatementTest extends AbstractRegressionTest {
static {
-// TESTS_NAMES = new String[] { "test074" };
+// TESTS_NAMES = new String[] { "testBug387612" };
// TESTS_NUMBERS = new int[] { 74, 75 };
// TESTS_RANGE = new int[] { 11, -1 };
}
@@ -5990,6 +5991,141 @@ public void test074() {
});
}
+// Bug 387612 - Unreachable catch block...exception is never thrown from the try
+// redundant exception in throws must not confuse downstream analysis
+public void testBug387612() {
+ String serialUID = "private static final long serialVersionUID=1L;";
+ runNegativeTest(
+ new String[] {
+ "E.java",
+ "public class E extends Exception {"+serialUID+"}\n",
+ "E1.java",
+ "public class E1 extends E {"+serialUID+"}\n",
+ "E2.java",
+ "public class E2 extends E {"+serialUID+"}\n",
+ "E3.java",
+ "public class E3 extends E {"+serialUID+"}\n",
+ "A.java",
+ "interface A {\n" +
+ " void foo(String a1, String a2) throws E1, E;\n" +
+ "}\n",
+ "B.java",
+ "interface B extends A {\n" +
+ " void foo(String a1, String a2) throws E;\n" +
+ "}\n",
+ "Client.java",
+ "public class Client {\n" +
+ " void test() {\n" +
+ " B b = new B() {\n" +
+ " public void foo(String a1, String a2) {}\n" +
+ " };\n" +
+ " try {\n" +
+ " b.foo(null, null);\n" +
+ " }\n" +
+ " catch (E1 e) {}\n" +
+ " catch (E2 e) {}\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in Client.java (at line 7)\n" +
+ " b.foo(null, null);\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Unhandled exception type E\n" +
+ "----------\n");
+}
+
+// Bug 387612 - Unreachable catch block...exception is never thrown from the try
+// - changed order in redundant 'throws' clause.
+public void testBug387612b() {
+ String serialUID = "private static final long serialVersionUID=1L;";
+ runNegativeTest(
+ new String[] {
+ "E.java",
+ "public class E extends Exception {"+serialUID+"}\n",
+ "E1.java",
+ "public class E1 extends E {"+serialUID+"}\n",
+ "E2.java",
+ "public class E2 extends E {"+serialUID+"}\n",
+ "E3.java",
+ "public class E3 extends E {"+serialUID+"}\n",
+ "A.java",
+ "interface A {\n" +
+ " void foo(String a1, String a2) throws E, E1;\n" +
+ "}\n",
+ "B.java",
+ "interface B extends A {\n" +
+ " void foo(String a1, String a2) throws E;\n" +
+ "}\n",
+ "Client.java",
+ "public class Client {\n" +
+ " void test() {\n" +
+ " B b = new B() {\n" +
+ " public void foo(String a1, String a2) {}\n" +
+ " };\n" +
+ " try {\n" +
+ " b.foo(null, null);\n" +
+ " }\n" +
+ " catch (E1 e) {}\n" +
+ " catch (E2 e) {}\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in Client.java (at line 7)\n" +
+ " b.foo(null, null);\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Unhandled exception type E\n" +
+ "----------\n");
+}
+
+// Bug 387612 - Unreachable catch block...exception is never thrown from the try
+// interface with redundant exceptions in throws is read from class file.
+public void testBug387612c() {
+ String serialUID = "private static final long serialVersionUID=1L;";
+ runConformTest(
+ new String[] {
+ "E.java",
+ "public class E extends Exception {"+serialUID+"}\n",
+ "E1.java",
+ "public class E1 extends E {"+serialUID+"}\n",
+ "E2.java",
+ "public class E2 extends E {"+serialUID+"}\n",
+ "A.java",
+ "interface A {\n" +
+ " void foo(String a1, String a2) throws E1, E;\n" +
+ "}\n",
+ "B.java",
+ "interface B extends A {\n" +
+ " void foo(String a1, String a2) throws E;\n" +
+ "}\n"
+ });
+ runNegativeTest(
+ new String[] {
+ "Client.java",
+ "public class Client {\n" +
+ " void test() {\n" +
+ " B b = new B() {\n" +
+ " public void foo(String a1, String a2) {}\n" +
+ " };\n" +
+ " try {\n" +
+ " b.foo(null, null);\n" +
+ " }\n" +
+ " catch (E1 e) {}\n" +
+ " catch (E2 e) {}\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in Client.java (at line 7)\n" +
+ " b.foo(null, null);\n" +
+ " ^^^^^^^^^^^^^^^^^\n" +
+ "Unhandled exception type E\n" +
+ "----------\n",
+ null,
+ false/*shouldFlush*/);
+}
+
public static Class testClass() {
return TryStatementTest.class;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index d3f5cbe..3d8930d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -11,7 +11,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 186342 [compiler][null] Using annotations for null checking
+ * Stephan Herrmann - Contributions for
+ * bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 387612 - Unreachable catch block...exception is never thrown from the try
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -3996,13 +3998,14 @@ public abstract class Scope {
mostSpecificExceptions = current.thrownExceptions;
}
int mostSpecificLength = mostSpecificExceptions.length;
- int nextLength = next.thrownExceptions.length;
+ ReferenceBinding[] nextExceptions = getFilteredExceptions(next);
+ int nextLength = nextExceptions.length;
SimpleSet temp = new SimpleSet(mostSpecificLength);
boolean changed = false;
nextException : for (int t = 0; t < mostSpecificLength; t++) {
ReferenceBinding exception = mostSpecificExceptions[t];
for (int s = 0; s < nextLength; s++) {
- ReferenceBinding nextException = next.thrownExceptions[s];
+ ReferenceBinding nextException = nextExceptions[s];
if (exception.isCompatibleWith(nextException)) {
temp.add(exception);
continue nextException;
@@ -4035,6 +4038,41 @@ public abstract class Scope {
return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous);
}
+ private ReferenceBinding[] getFilteredExceptions(MethodBinding method) {
+ // http://bugs.eclipse.org/387612 - Unreachable catch block...exception is never thrown from the try
+ // Need to filter redundant exceptions within the same throws clause.
+ // In this filtering the *most general* exception wins in order to capture all possible exceptions
+ // that could be thrown by the given method.
+ ReferenceBinding[] allExceptions = method.thrownExceptions;
+ int length = allExceptions.length;
+ if (length < 2) return allExceptions;
+ ReferenceBinding[] filteredExceptions = new ReferenceBinding[length];
+ int count = 0;
+ currents: for (int i = 0; i < length; i++) {
+ ReferenceBinding currentException = allExceptions[i];
+ for (int j = 0; j < length; j++) {
+ if (i == j) continue;
+ if (currentException == allExceptions[j]) {
+ // duplicate same exception
+ if (i < j)
+ break; // take only the first occurrence
+ else
+ continue currents; // skip
+ }
+ if (currentException.isCompatibleWith(allExceptions[j])) {
+ continue currents; // skip
+ }
+ }
+ filteredExceptions[count++] = currentException;
+ }
+ if (count != length) {
+ ReferenceBinding[] tmp = new ReferenceBinding[count];
+ System.arraycopy(filteredExceptions, 0, tmp, 0, count);
+ return tmp;
+ }
+ return allExceptions;
+ }
+
public final ClassScope outerMostClassScope() {
ClassScope lastClassScope = null;
Scope scope = this;