Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAyushman Jain2012-05-29 10:04:57 +0000
committerJayaprakash Arthanareeswaran2013-01-02 08:24:32 +0000
commit650d34a55f295affa1498bddd4cfe460109baef3 (patch)
treec3adb7083943f2162b48ee29850c93d53eb92cc5
parentf4f6ce25213802ef8d63ed0a83e5e0e2b60e306f (diff)
downloadeclipse.jdt.core-650d34a55f295affa1498bddd4cfe460109baef3.tar.gz
eclipse.jdt.core-650d34a55f295affa1498bddd4cfe460109baef3.tar.xz
eclipse.jdt.core-650d34a55f295affa1498bddd4cfe460109baef3.zip
Fixed bug 380313: Inconsistent stack error when using Java 1.7
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java83
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java298
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java10
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java12
4 files changed, 402 insertions, 1 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
index 32b50af3ef..2e6883fda4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
@@ -2360,6 +2360,89 @@ public void testBug338234d() {
"The local variable i may not have been initialized\n" +
"----------\n");
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=380313
+// Verify that the code runs fine with all compliance levels.
+public void testBug380313() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_5)
+ return;
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ "public void foo() throws Exception {\n" +
+ " int i = 1;\n" +
+ " int j = 2;\n" +
+ " try {\n" +
+ " if ((bar() == 1)) {\n" +
+ " if ((i == 1)) {\n" +
+ " int n = bar();\n" +
+ " if (n == 35) {\n" +
+ " j = 2;\n" +
+ " } else {\n" +
+ " if (bar() > 0)\n" +
+ " return;\n" +
+ " }\n" +
+ " } else {\n" +
+ " throw new Exception();\n" +
+ " }\n" +
+ " } else {\n" +
+ " throw new Exception();\n" +
+ " }\n" +
+ " if (bar() == 0)\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " bar();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " private int bar() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " }\n" +
+ "}\n"
+ },
+ "");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=380313
+// try with resources
+// Verify that the code runs fine with all compliance levels.
+public void testBug380313b() {
+ if (this.complianceLevel < ClassFileConstants.JDK1_7)
+ return;
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileInputStream;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ "public void foo() throws Exception {\n" +
+ " int i = 1;\n" +
+ " try {\n" +
+ " try (FileInputStream fis = new FileInputStream(\"\")) {\n" +
+ " if (i == 2)" +
+ " return;\n" +
+ " }\n" +
+ " if (i == 35) \n" +
+ " return;\n" +
+ " } catch(IOException e) {\n" +
+ " bar();\n" +
+ " } finally {\n" +
+ " bar();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " private int bar() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " }\n" +
+ "}\n"
+ },
+ "");
+}
public static Class testClass() {
return FlowAnalysisTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
index 8b83af74d6..f6d4246872 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
@@ -34,7 +34,7 @@ public class StackMapAttributeTest extends AbstractRegressionTest {
// All specified tests which does not belong to the class are skipped...
static {
// TESTS_PREFIX = "testBug95521";
-// TESTS_NAMES = new String[] { "testBug359495" };
+// TESTS_NAMES = new String[] { "testBug380313" };
// TESTS_NUMBERS = new int[] { 53 };
// TESTS_RANGE = new int[] { 23 -1,};
}
@@ -7616,4 +7616,300 @@ public class StackMapAttributeTest extends AbstractRegressionTest {
},
"SUCCESS");
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=380313
+ // Verify the generated code does not have same branch target for the 2 return statements
+ public void testBug380313() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ "public void foo() throws Exception {\n" +
+ " int i = 1;\n" +
+ " try {\n" +
+ " if (i == 1) {\n" +
+ " int n = bar();\n" +
+ " if (n == 35)\n" +
+ " return;\n" +
+ " } else {\n" +
+ " throw new Exception();\n" +
+ " }\n" +
+ " if (i == 0)\n" +
+ " return;\n" +
+ " } finally {\n" +
+ " bar();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " private int bar() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "SUCCESS");
+
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class"));
+ String actualOutput =
+ disassembler.disassemble(
+ classFileBytes,
+ "\n",
+ ClassFileBytesDisassembler.DETAILED);
+
+ String expectedOutput =
+ " // Method descriptor #6 ()V\n" +
+ " // Stack: 2, Locals: 4\n" +
+ " public void foo() throws java.lang.Exception;\n" +
+ " 0 iconst_1\n" +
+ " 1 istore_1 [i]\n" +
+ " 2 iload_1 [i]\n" +
+ " 3 iconst_1\n" +
+ " 4 if_icmpne 24\n" +
+ " 7 aload_0 [this]\n" +
+ " 8 invokespecial X.bar() : int [18]\n" +
+ " 11 istore_2 [n]\n" +
+ " 12 iload_2 [n]\n" +
+ " 13 bipush 35\n" +
+ " 15 if_icmpne 32\n" +
+ " 18 aload_0 [this]\n" +
+ " 19 invokespecial X.bar() : int [18]\n" +
+ " 22 pop\n" +
+ " 23 return\n" +
+ " 24 new java.lang.Exception [16]\n" +
+ " 27 dup\n" +
+ " 28 invokespecial java.lang.Exception() [22]\n" +
+ " 31 athrow\n" +
+ " 32 iload_1 [i]\n" +
+ " 33 ifne 50\n" +
+ " 36 aload_0 [this]\n" +
+ " 37 invokespecial X.bar() : int [18]\n" +
+ " 40 pop\n" +
+ " 41 return\n" +
+ " 42 astore_3\n" +
+ " 43 aload_0 [this]\n" +
+ " 44 invokespecial X.bar() : int [18]\n" +
+ " 47 pop\n" +
+ " 48 aload_3\n" +
+ " 49 athrow\n" +
+ " 50 aload_0 [this]\n" +
+ " 51 invokespecial X.bar() : int [18]\n" +
+ " 54 pop\n" +
+ " 55 return\n" +
+ " Exception Table:\n" +
+ " [pc: 2, pc: 18] -> 42 when : any\n" +
+ " [pc: 24, pc: 36] -> 42 when : any\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 3]\n" +
+ " [pc: 2, line: 5]\n" +
+ " [pc: 7, line: 6]\n" +
+ " [pc: 12, line: 7]\n" +
+ " [pc: 18, line: 15]\n" +
+ " [pc: 23, line: 8]\n" +
+ " [pc: 24, line: 10]\n" +
+ " [pc: 32, line: 12]\n" +
+ " [pc: 36, line: 15]\n" +
+ " [pc: 41, line: 13]\n" +
+ " [pc: 42, line: 14]\n" +
+ " [pc: 43, line: 15]\n" +
+ " [pc: 48, line: 16]\n" +
+ " [pc: 50, line: 15]\n" +
+ " [pc: 55, line: 17]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 56] local: this index: 0 type: X\n" +
+ " [pc: 2, pc: 56] local: i index: 1 type: int\n" +
+ " [pc: 12, pc: 24] local: n index: 2 type: int\n" +
+ " Stack map table: number of frames 4\n" +
+ " [pc: 24, append: {int}]\n" +
+ " [pc: 32, same]\n" +
+ " [pc: 42, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n" +
+ " [pc: 50, same]\n";
+ int index = actualOutput.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(actualOutput, 2));
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, actualOutput);
+ }
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=380313
+ // Verify the generated code does not have same branch target for the 2 return statements
+ public void testBug380313b() throws Exception {
+ if (this.complianceLevel < ClassFileConstants.JDK1_7)
+ return;
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.FileInputStream;\n" +
+ "import java.io.IOException;\n" +
+ "public class X {\n" +
+ "public void foo() throws Exception {\n" +
+ " int i = 1;\n" +
+ " try {\n" +
+ " try (FileInputStream fis = new FileInputStream(\"\")) {\n" +
+ " if (i == 2)" +
+ " return;\n" +
+ " }\n" +
+ " if (i == 35) \n" +
+ " return;\n" +
+ " } catch(IOException e) {\n" +
+ " bar();\n" +
+ " } finally {\n" +
+ " bar();\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " private int bar() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "SUCCESS");
+
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class"));
+ String actualOutput =
+ disassembler.disassemble(
+ classFileBytes,
+ "\n",
+ ClassFileBytesDisassembler.DETAILED);
+
+ String expectedOutput =
+ " // Method descriptor #6 ()V\n" +
+ " // Stack: 3, Locals: 6\n" +
+ " public void foo() throws java.lang.Exception;\n" +
+ " 0 iconst_1\n" +
+ " 1 istore_1 [i]\n" +
+ " 2 aconst_null\n" +
+ " 3 astore_2\n" +
+ " 4 aconst_null\n" +
+ " 5 astore_3\n" +
+ " 6 new java.io.FileInputStream [18]\n" +
+ " 9 dup\n" +
+ " 10 ldc <String \"\"> [20]\n" +
+ " 12 invokespecial java.io.FileInputStream(java.lang.String) [22]\n" +
+ " 15 astore 4 [fis]\n" +
+ " 17 iload_1 [i]\n" +
+ " 18 iconst_2\n" +
+ " 19 if_icmpne 38\n" +
+ " 22 aload 4 [fis]\n" +
+ " 24 ifnull 32\n" +
+ " 27 aload 4 [fis]\n" +
+ " 29 invokevirtual java.io.FileInputStream.close() : void [25]\n" +
+ " 32 aload_0 [this]\n" + // return 1
+ " 33 invokespecial X.bar() : int [28]\n" +
+ " 36 pop\n" +
+ " 37 return\n" +
+ " 38 aload 4 [fis]\n" +
+ " 40 ifnull 86\n" +
+ " 43 aload 4 [fis]\n" +
+ " 45 invokevirtual java.io.FileInputStream.close() : void [25]\n" +
+ " 48 goto 86\n" +
+ " 51 astore_2\n" +
+ " 52 aload 4 [fis]\n" +
+ " 54 ifnull 62\n" +
+ " 57 aload 4 [fis]\n" +
+ " 59 invokevirtual java.io.FileInputStream.close() : void [25]\n" +
+ " 62 aload_2\n" +
+ " 63 athrow\n" +
+ " 64 astore_3\n" +
+ " 65 aload_2\n" +
+ " 66 ifnonnull 74\n" +
+ " 69 aload_3\n" +
+ " 70 astore_2\n" +
+ " 71 goto 84\n" +
+ " 74 aload_2\n" +
+ " 75 aload_3\n" +
+ " 76 if_acmpeq 84\n" +
+ " 79 aload_2\n" +
+ " 80 aload_3\n" +
+ " 81 invokevirtual java.lang.Throwable.addSuppressed(java.lang.Throwable) : void [32]\n" +
+ " 84 aload_2\n" +
+ " 85 athrow\n" +
+ " 86 iload_1 [i]\n" +
+ " 87 bipush 35\n" +
+ " 89 if_icmpne 122\n" +
+ " 92 aload_0 [this]\n" + // return 2
+ " 93 invokespecial X.bar() : int [28]\n" +
+ " 96 pop\n" +
+ " 97 return\n" +
+ " 98 astore_2 [e]\n" +
+ " 99 aload_0 [this]\n" +
+ " 100 invokespecial X.bar() : int [28]\n" +
+ " 103 pop\n" +
+ " 104 aload_0 [this]\n" +
+ " 105 invokespecial X.bar() : int [28]\n" +
+ " 108 pop\n" +
+ " 109 goto 127\n" +
+ " 112 astore 5\n" +
+ " 114 aload_0 [this]\n" +
+ " 115 invokespecial X.bar() : int [28]\n" +
+ " 118 pop\n" +
+ " 119 aload 5\n" +
+ " 121 athrow\n" +
+ " 122 aload_0 [this]\n" +
+ " 123 invokespecial X.bar() : int [28]\n" +
+ " 126 pop\n" +
+ " 127 return\n" +
+ " Exception Table:\n" +
+ " [pc: 17, pc: 22] -> 51 when : any\n" +
+ " [pc: 32, pc: 38] -> 51 when : any\n" +
+ " [pc: 6, pc: 64] -> 64 when : any\n" +
+ " [pc: 2, pc: 32] -> 98 when : java.io.IOException\n" +
+ " [pc: 38, pc: 92] -> 98 when : java.io.IOException\n" +
+ " [pc: 2, pc: 32] -> 112 when : any\n" +
+ " [pc: 38, pc: 92] -> 112 when : any\n" +
+ " [pc: 98, pc: 104] -> 112 when : any\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 5]\n" +
+ " [pc: 2, line: 7]\n" +
+ " [pc: 17, line: 8]\n" +
+ " [pc: 22, line: 9]\n" +
+ " [pc: 32, line: 15]\n" +
+ " [pc: 37, line: 8]\n" +
+ " [pc: 38, line: 9]\n" +
+ " [pc: 86, line: 10]\n" +
+ " [pc: 92, line: 15]\n" +
+ " [pc: 97, line: 11]\n" +
+ " [pc: 98, line: 12]\n" +
+ " [pc: 99, line: 13]\n" +
+ " [pc: 104, line: 15]\n" +
+ " [pc: 112, line: 14]\n" +
+ " [pc: 114, line: 15]\n" +
+ " [pc: 119, line: 16]\n" +
+ " [pc: 122, line: 15]\n" +
+ " [pc: 127, line: 17]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 128] local: this index: 0 type: X\n" +
+ " [pc: 2, pc: 128] local: i index: 1 type: int\n" +
+ " [pc: 17, pc: 62] local: fis index: 4 type: java.io.FileInputStream\n" +
+ " [pc: 99, pc: 104] local: e index: 2 type: java.io.IOException\n" +
+ " Stack map table: number of frames 12\n" +
+ " [pc: 32, full, stack: {}, locals: {X, int, java.lang.Throwable, java.lang.Throwable, java.io.FileInputStream}]\n" +
+ " [pc: 38, same]\n" +
+ " [pc: 51, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n" +
+ " [pc: 62, chop 1 local(s)]\n" +
+ " [pc: 64, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n" +
+ " [pc: 74, same]\n" +
+ " [pc: 84, same]\n" +
+ " [pc: 86, chop 2 local(s)]\n" +
+ " [pc: 98, same_locals_1_stack_item, stack: {java.io.IOException}]\n" +
+ " [pc: 112, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n" +
+ " [pc: 122, same]\n" +
+ " [pc: 127, same]\n";
+ int index = actualOutput.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(actualOutput, 2));
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, actualOutput);
+ }
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
index cb789a4ad4..68eb561b78 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
@@ -36,6 +36,16 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
}
}
+ if (this.explicitDeclarations > 0) {
+ // cleanup assignment info for locals that are scoped to this block:
+ LocalVariableBinding[] locals = this.scope.locals;
+ if (locals != null) {
+ int numLocals = this.scope.localIndex;
+ for (int i = 0; i < numLocals; i++) {
+ flowInfo.resetAssignmentInfo(locals[i]);
+ }
+ }
+ }
return flowInfo;
}
/**
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 a3385251e2..343ca0ea01 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
@@ -148,6 +148,12 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
}
if (resourcesLength > 0) {
this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo);
+ // the resources are not in scope after the try block, so remove their assignment info
+ // to avoid polluting the state indices. However, do this after the postTryInitStateIndex is calculated since
+ // it is used to add or remove assigned resources during code gen
+ for (int i = 0; i < resourcesLength; i++) {
+ tryInfo.resetAssignmentInfo(this.resources[i].binding);
+ }
}
// check unreachable catch blocks
handlingContext.complainIfUnusedExceptionHandlers(this.scope, this);
@@ -274,6 +280,12 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
}
if (resourcesLength > 0) {
this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo);
+ // the resources are not in scope after the try block, so remove their assignment info
+ // to avoid polluting the state indices. However, do this after the postTryInitStateIndex is calculated since
+ // it is used to add or remove assigned resources during code gen
+ for (int i = 0; i < resourcesLength; i++) {
+ tryInfo.resetAssignmentInfo(this.resources[i].binding);
+ }
}
// check unreachable catch blocks
handlingContext.complainIfUnusedExceptionHandlers(this.scope, this);

Back to the top