diff options
author | Olivier Thomann | 2019-09-23 19:54:44 +0000 |
---|---|---|
committer | Jay Arthanareeswaran | 2019-09-24 07:39:44 +0000 |
commit | 212e6b23af942ca28f9a8eed4ca33c2053dc2108 (patch) | |
tree | 730994f3abac6b88a77229831072e927c425279f | |
parent | 4cce8d539640bf79f986bb9a432b2351d6a08608 (diff) | |
download | eclipse.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
Change-Id: I628b2263e573b29ad15c53ae9b7c3c5330a03432
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)); } } |