Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Thomann2019-09-23 19:54:44 +0000
committerJay Arthanareeswaran2019-09-24 07:39:44 +0000
commit212e6b23af942ca28f9a8eed4ca33c2053dc2108 (patch)
tree730994f3abac6b88a77229831072e927c425279f
parent4cce8d539640bf79f986bb9a432b2351d6a08608 (diff)
downloadeclipse.jdt.core-212e6b23af942ca28f9a8eed4ca33c2053dc2108.tar.gz
eclipse.jdt.core-212e6b23af942ca28f9a8eed4ca33c2053dc2108.tar.xz
eclipse.jdt.core-212e6b23af942ca28f9a8eed4ca33c2053dc2108.zip
Bug 551368 - VerifyError with latest jdt.core code on master
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java47
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java36
2 files changed, 67 insertions, 16 deletions
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 0261c95932..93b1e34602 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
@@ -8722,4 +8722,51 @@ public class StackMapAttributeTest extends AbstractRegressionTest {
assertEquals("Wrong contents", expectedOutput, actualOutput);
}
}
+
+ public void test551368() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "interface A {\n" +
+ "}\n" +
+ "class B implements A {\n" +
+ " public C c;\n" +
+ " \n" +
+ " protected B original() {\n" +
+ " return this;\n" +
+ " }\n" +
+ "}\n" +
+ "class C {\n" +
+ " C parent;\n" +
+ " A context;\n" +
+ "}\n" +
+ "class F extends C {\n" +
+ " \n" +
+ "}\n" +
+ "class G extends C {\n" +
+ " \n" +
+ "}\n" +
+ "abstract class D implements A {\n" +
+ " public F c;\n" +
+ "}\n" +
+ "class E implements A {\n" +
+ " public G c;\n" +
+ "}\n" +
+ "public class X {\n" +
+ " boolean foo(A a) {\n" +
+ " if (a instanceof B && a != ((B) a).original())\n" +
+ " return true;\n" +
+ " C aC = a instanceof D ? ((D) a).c :\n" +
+ " a instanceof E ? ((E) a).c : \n" +
+ " a instanceof B ? ((B) a).c :\n" +
+ " null;\n" +
+ " return aC != null ? foo(aC.parent.context) : false;\n" +
+ " }\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(\"SUCCESS\");\n" +
+ " }\n" +
+ "}",
+ },
+ "SUCCESS");
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index ad8b1ef6b9..a966aed576 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -6041,7 +6041,7 @@ public class ClassFile implements TypeConstants, TypeIds {
initializeDefaultLocals(frame, methodBinding, maxLocals, codeLength);
}
frame.pc = -1;
- add(frames, frame.duplicate());
+ add(frames, frame.duplicate(), scope);
addRealJumpTarget(realJumpTarget, -1);
for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
ExceptionLabel exceptionLabel = this.codeStream.exceptionLabels[i];
@@ -6076,7 +6076,7 @@ public class ClassFile implements TypeConstants, TypeIds {
StackMapFrame currentFrame = frames.get(Integer.valueOf(currentPC));
if (currentFrame == null) {
currentFrame = createNewFrame(currentPC, frame, isClinit, methodBinding);
- add(frames, currentFrame);
+ add(frames, currentFrame, scope);
} else {
frame = currentFrame.merge(frame.duplicate(), scope).duplicate();
}
@@ -6623,7 +6623,7 @@ public class ClassFile implements TypeConstants, TypeIds {
case Opcodes.OPC_ifle:
frame.numberOfStackItems--;
int jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
break;
case Opcodes.OPC_if_icmpeq:
@@ -6636,12 +6636,12 @@ public class ClassFile implements TypeConstants, TypeIds {
case Opcodes.OPC_if_acmpne:
frame.numberOfStackItems -= 2;
jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
break;
case Opcodes.OPC_goto:
jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
addRealJumpTarget(realJumpTarget, pc - codeOffset);
break;
@@ -6653,7 +6653,7 @@ public class ClassFile implements TypeConstants, TypeIds {
}
// default offset
jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4; // default
int low = i4At(bytecodes, 0, pc);
pc += 4;
@@ -6663,7 +6663,7 @@ public class ClassFile implements TypeConstants, TypeIds {
for (int i = 0; i < length; i++) {
// pair offset
jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4;
}
break;
@@ -6674,7 +6674,7 @@ public class ClassFile implements TypeConstants, TypeIds {
pc++;
}
jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4; // default offset
int npairs = (int) u4At(bytecodes, 0, pc);
pc += 4; // npair value
@@ -6682,7 +6682,7 @@ public class ClassFile implements TypeConstants, TypeIds {
pc += 4; // case value
// pair offset
jumpPC = currentPC + i4At(bytecodes, 0, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 4;
}
break;
@@ -7037,12 +7037,12 @@ public class ClassFile implements TypeConstants, TypeIds {
case Opcodes.OPC_ifnonnull:
frame.numberOfStackItems--;
jumpPC = currentPC + i2At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 3;
break;
case Opcodes.OPC_goto_w:
jumpPC = currentPC + i4At(bytecodes, 1, pc);
- addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding));
+ addRealJumpTarget(realJumpTarget, jumpPC, frames, createNewFrame(jumpPC, frame, isClinit, methodBinding), scope);
pc += 5;
addRealJumpTarget(realJumpTarget, pc - codeOffset); // handle infinite loop
break;
@@ -7097,15 +7097,19 @@ public class ClassFile implements TypeConstants, TypeIds {
realJumpTarget.add(Integer.valueOf(pc));
}
- private void addRealJumpTarget(Set realJumpTarget, int pc, Map frames, StackMapFrame frame) {
+ private void addRealJumpTarget(Set realJumpTarget, int pc, Map frames, StackMapFrame frame, Scope scope) {
realJumpTarget.add(Integer.valueOf(pc));
- add(frames, frame);
+ add(frames, frame, scope);
}
- private void add(Map frames, StackMapFrame frame) {
+ private void add(Map<Integer, StackMapFrame> frames, StackMapFrame frame, Scope scope) {
Integer key = Integer.valueOf(frame.pc);
- if(!frames.containsKey(key)) {
- frames.put(Integer.valueOf(frame.pc), frame);
+ StackMapFrame existingFrame = frames.get(key);
+ if(existingFrame == null) {
+ frames.put(key, frame);
+ } else {
+ // we need to merge
+ frames.put(key, existingFrame.merge(frame, scope));
}
}

Back to the top