Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package org.eclipse.jdt.internal.compiler.codegen;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
Expand Down Expand Up @@ -44,6 +45,9 @@ public class StackMapFrame {
*/
public boolean adoptStackShape = true;

// if the textually preceding stack frame shape is not adopted, we know nothing about this frame's verification types.
private static final VerificationTypeInfo [] UNKNOWN_STACK_ITEMS = new VerificationTypeInfo[0];

public StackMapFrame(int initialLocalSize) {
this.locals = new VerificationTypeInfo[initialLocalSize];
this.numberOfLocals = -1;
Expand Down Expand Up @@ -118,6 +122,8 @@ public StackMapFrame duplicate() {
final VerificationTypeInfo verificationTypeInfo = this.stackItems[i];
result.stackItems[i] = getCachedValue(cache, verificationTypeInfo);
}
} else if (!this.adoptStackShape) {
result.stackItems = UNKNOWN_STACK_ITEMS;
}
return result;
}
Expand Down Expand Up @@ -404,6 +410,8 @@ public StackMapFrame merge(StackMapFrame frame, Scope scope) {
for (int i = 0, max = this.numberOfStackItems; i < max; i++) {
this.stackItems[i] = this.stackItems[i].merge(frame.stackItems[i], scope);
}
} else if (this.stackItems == UNKNOWN_STACK_ITEMS) {
this.stackItems = Arrays.copyOf(frame.stackItems, this.numberOfStackItems = frame.numberOfStackItems);
}
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8604,4 +8604,71 @@ private static BigDecimal unusedMethod2(BigDecimal value, BigDecimal otherValue)
},
"");
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/5201
// VerifyError: Instruction type does not match stack map with for loop in switch
public void testIssue5201() {
this.runConformTest(
new String[] {
"X.java",
"""
public class X {
public static void main(String[] args) {
System.out.println(10 + switch ("B") {
default -> {
for (int i = 0; i < 10; i++)
System.out.println(i);
yield "A";
}
case "B" -> "B";
});
}
}
"""
},
"10B");
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/5201
// VerifyError: Instruction type does not match stack map with for loop in switch
public void testIssue5201_full() {
this.runConformTest(
new String[] {
"X.java",
"""
import java.util.Collection;
import java.util.Set;

public class X {

public static class Dummy {

}

public static class ExtendedDummy extends Dummy {

}

public static void main(String[] args) {
test(ExtendedDummy.class, switch ("B") {
case "A" -> {
for (int i = 0; i < 10; i++)
System.out.println(i);

yield Set.of("NoopA");
}
case "B" -> Set.of("NoopB");
default -> throw new IllegalArgumentException();
});
}

public static <T extends Dummy> void test(Class<T> cls, Collection<String> entities) {
entities.forEach(e -> System.out.println(e));
}
}
"""
},
"NoopB");
}

}
Loading