RFR: 8353565: Javac throws "inconsistent stack types at join point" exception

Chen Liang liach at openjdk.org
Mon Apr 14 23:37:45 UTC 2025


On Mon, 14 Apr 2025 23:31:09 GMT, Chen Liang <liach at openjdk.org> wrote:

>> Consider code like:
>> 
>> public class T {
>>     private Object computeTypeAtMergePoint1(int i) {
>>         return (Object) switch (i) {
>>             case 0 -> switch (i) {
>>                 case 0 -> { yield new A(); }
>>                 default -> { yield new B(); }
>>             };
>>             default -> switch (i) {
>>                 case 0 -> { yield new C(); }
>>                 default -> { yield new D(); }
>>             };
>>         };
>>     }
>>     enum E {A, B}
>>     interface I1 {}
>>     class A implements I1 {}
>>     class B implements I1 {}
>>     interface I2 {}
>>     class C implements I2 {}
>>     class D implements I2 {}
>> 
>> }
>> 
>> 
>> Compiling this leads to a crash:
>> 
>> $ .../jdk-24/bin/javac  /tmp/T.java 
>> An exception has occurred in the compiler (24-internal). Please file a bug against the Java compiler via the Java bug reporting page (https://bugreport.java.com) after checking the Bug Database (https://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
>> java.lang.AssertionError: inconsistent stack types at join point
>>         at jdk.compiler/com.sun.tools.javac.jvm.Code$State.error(Code.java:1824)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Code$State.join(Code.java:1814)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Code.resolve(Code.java:1525)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Code.resolvePending(Code.java:1556)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Code.emitop(Code.java:382)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Code.emitop0(Code.java:511)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitReturn(Gen.java:1905)
>>         at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1773)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:623)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:609)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStats(Gen.java:660)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.internalVisitBlock(Gen.java:1121)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitBlock(Gen.java:1085)
>>         at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1137)
>>         at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
>>         at jdk.compiler/com.sun.tools.jav...
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java line 1814:
> 
>> 1812:                     types.isSubtype(t, tother) ? tother :
>> 1813:                     types.isSubtype(tother, t) ? t :
>> 1814:                     commonSuperClass(t, tother);
> 
> Are the `isSubtype()` or `t==tother` checks above still necessary? Like do those fast paths not exist in `types::lub`?

Just checked, lub is a varargs call and is slow. However, I think the fast path merge logic `t==tother? ... ` should be in `commonSuperClass`.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/24617#discussion_r2043166910


More information about the compiler-dev mailing list