Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8302865

Illegal bytecode for break from if with instanceof pattern matching condition

XMLWordPrintable

    • b03
    • generic
    • generic

        ADDITIONAL SYSTEM INFORMATION :
        Same result was obtained when testing under OSX/ARM64.

        A DESCRIPTION OF THE PROBLEM :
        When a Java method contains a labeled if condition with an instanceof pattern matching condition and then in the body does a break using that label, the compiler doesn't complain if any successor statements dereference the pattern variable. The produced code is illegal and results in a VerifyError when executed in the JVM.

        The simple example under "Source code for an executable test case results in the following error when compiled and executed:

        Error: Unable to initialize main class T
        Caused by: java.lang.VerifyError: Bad local variable type
        Exception Details:
          Location:
            T.main([Ljava/lang/String;)V @18: aload_2
          Reason:
            Type top (current frame, locals[2]) is not assignable to reference type
          Current Frame:
            bci: @18
            flags: { }
            locals: { '[Ljava/lang/String;', 'java/lang/Object' }
            stack: { 'java/io/PrintStream' }
          Bytecode:
            0000000: 1207 4c2b c100 0999 0008 2bc0 0009 4db2
            0000010: 000b 2cb6 0011 b1
          Stackmap Table:
            append_frame(@15,Object[#2])


        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Compile and execute the example class provided in "Source code for an executable test case".

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The code should fail to compile, because when breaking out of the if body the object `o` tested with instanceof is known not to be of type String and the pattern variable `s` should therefore not be dereferencable.
        ACTUAL -
        The code is compiled successfully (javap output pasted below) but fails to run in the JVM.

          public static void main(java.lang.String[]);
            Code:
               0: ldc #7 // String hello
               2: astore_1
               3: aload_1
               4: instanceof #9 // class java/lang/String
               7: ifeq 15
              10: aload_1
              11: checkcast #9 // class java/lang/String
              14: astore_2
              15: getstatic #11 // Field java/lang/System.out:Ljava/io/PrintStream;
              18: aload_2
              19: invokevirtual #17 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
              22: return


        ---------- BEGIN SOURCE ----------
        class T {
            public static void main(String[] args) {
                Object o = "hello";
                X: if (!(o instanceof String s)) {
                    break X;
                }
                System.out.println(s);
            }
        }

        ---------- END SOURCE ----------

        FREQUENCY : always


              jlahoda Jan Lahoda
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: