Integrated: 8358801: javac produces class that does not pass verifier.

Jan Lahoda jlahoda at openjdk.org
Thu Jul 3 07:20:49 UTC 2025


On Tue, 17 Jun 2025 10:01:02 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:

> Consider code like:
> 
> 
> public class Main {
> 
>     private boolean test(String s, int i) {
>         if (s.subSequence(0, 1) instanceof Runnable r) {
>             return true;
>         }
> 
>         Integer dummy;
>         switch (i) {
>             case 0:
>                 String clashing = null;
>                 return true;
>             default:
>                 return true;
>         }
>     }
> 
>     public static void main(String[] args) {
>     }
> }
> 
> 
> javac will produce code that won't (rightfully) pass the verifier:
> 
> 
> $ java Main.java
> Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 49
> Exception Details:
>   Location:
>     Main.test(Ljava/lang/String;I)Z @49: iconst_1
>   Reason:
>     Type top (current frame, locals[4]) is not assignable to 'java/lang/String' (stack map, locals[4])
>   Current Frame:
>     bci: @25
>     flags: { }
>     locals: { 'Main', 'java/lang/String', integer }
>     stack: { integer }
>   Stackmap Frame:
>     bci: @49
>     flags: { }
>     locals: { 'Main', 'java/lang/String', integer, top, 'java/lang/String' }
>     stack: { }
>   Bytecode:
>     0000000: 2b03 04b6 0007 3a04 1904 c100 0d99 000b
>     0000010: 1904 c000 0d4e 04ac 1cab 0000 0000 0018
>     0000020: 0000 0001 0000 0000 0000 0013 013a 0404
>     0000030: ac04 ac
>   Stackmap Table:
>     same_frame(@24)
>     same_frame(@44)
>     append_frame(@49,Top,Object[#8])
> 
>         at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
>         at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3035)
>         at java.base/java.lang.Class.getMethodsRecursive(Class.java:3177)
>         at java.base/java.lang.Class.findMethod(Class.java:2465)
>         at java.base/java.lang.System$1.findMethod(System.java:1980)
>         at java.base/jdk.internal.misc.MethodFinder.findMainMethod(MethodFinder.java:86)
>         at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.execute(SourceLauncher.java:194)
>         at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.run(SourceLauncher.java:138)
>         at jdk.compiler/com.sun.tools.javac.launcher.SourceLauncher.main(SourceLauncher.java:76)
> 
> 
> 
> Now, the problem, as far as I can tell, is this: javac will desugar the pattern matching instanceof along the lines of:
> 
> 
> if (... (var $temp = s.subSequence(0, 1) in ... && ...) ...) {
>     return true;
> }
> 
> 
> (`$temp` is register/local variable number 4)
> specifically, note the `&&` in the middle of the let expression, and that the expression is in the conditional position. What happens here is...

This pull request has now been integrated.

Changeset: fd13e1ce
Author:    Jan Lahoda <jlahoda at openjdk.org>
URL:       https://git.openjdk.org/jdk/commit/fd13e1ce9805a903ab60ad9b476eb5a6687d22ee
Stats:     144 lines in 2 files changed: 144 ins; 0 del; 0 mod

8358801: javac produces class that does not pass verifier.

Reviewed-by: mcimadamore, liach

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

PR: https://git.openjdk.org/jdk/pull/25849


More information about the compiler-dev mailing list