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

Unexpected problems when combining record patterns and switch => VerifyError

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      macOS Monterey 12.6.4

      A DESCRIPTION OF THE PROBLEM :
      Unexpected problems when combining record patterns and switch resulting in a java.lang.VerifyError: Bad type on operand stack
         


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create record
      jshell> record MyPair<T1, T2>(T1 first, T2 second) {
         ...> }

      2. Create Method
      jshell> static void recordInferenceJdk19(MyPair<String, Integer> pair) {
         ...> switch (pair) {
         ...> case MyPair<String, Integer>(var text, var count) when text.contains("Michael") ->
         ...> System.out.println(text + " is " + count + " years old");
         ...> case MyPair<String, Integer>(var text, var count) when count > 5 && count < 10 ->
         ...> System.out.println("repeated " + text.repeat(count));
         ...> case MyPair<String, Integer>(var text, var count) -> System.out.println(text + count);
         ...> default -> System.out.println("PENG");
         ...> }
         ...> }


      3. Call Method
      jshell> recordInferenceJdk19(new MyPair<>("Michael", 52))
      | Ausnahme java.lang.VerifyError: Bad type on operand stack


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The suitable case should be selected. Like with instanceof

      When calling the method

      * recordInferenceJdk19(new MyPair<>("Michael", 52))
      => case 1 should match
      => "Michael is 52 years old"

      * recordInferenceJdk19(new MyPair<>("Mike", 7))
      => case 2 should match
      => "repeated MikeMikeMikeMikeMikeMikeMike"

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

      INSTANCEOF-Version works well

      jshell> static void recordInferenceJdk19io(MyPair<String, Integer> pair) {
         ...> if (pair instanceof MyPair<String, Integer>(var text, var count) && text.contains("Michael"))
         ...> System.out.println(text + " is " + count + " years old");
         ...> else if (pair instanceof MyPair<String, Integer>(var text, var count) && count > 5 && count < 10)
         ...> System.out.println("repeated " + text.repeat(count));
         ...> else if (pair instanceof MyPair<String, Integer>(var text, var count))
         ...> System.out.println(text + count);
         ...> else
         ...> System.out.println("PENG");
         ...> }
      | Erstellt Methode recordInferenceJdk19io(MyPair<String, Integer>)

      jshell> recordInferenceJdk19io(new MyPair<>("Mike", 7))
      repeated MikeMikeMikeMikeMikeMikeMike

      jshell> recordInferenceJdk19io(new MyPair<>("Michael", 52))
      Michael is 52 years old

      ACTUAL -
      jshell> recordInferenceJdk19(new MyPair<>("Michael", 52))
      | Ausnahme java.lang.VerifyError: Bad type on operand stack
      Exception Details:
        Location:
          REPL/$JShell$17B.recordInferenceJdk19(LREPL/$JShell$16$MyPair;)V @181: invokevirtual
        Reason:
          Type 'java/lang/String' (current frame, stack[2]) is not assignable to 'java/lang/Integer'
        Current Frame:
          bci: @181
          flags: { }
          locals: { 'REPL/$JShell$16$MyPair', 'REPL/$JShell$16$MyPair', integer, 'REPL/$JShell$16$MyPair', 'java/lang/String', top, 'java/lang/String', integer, 'java/lang/Integer', integer }
          stack: { 'java/io/PrintStream', 'java/lang/String', 'java/lang/String' }
        Bytecode:
          0000000: 2a59 b800 0757 4c03 3d2b 1cba 000d 0000
          0000010: ab00 0000 0000 00c8 0000 0001 0000 0000
          0000020: 0000 0014 2b4e 2db6 0011 c000 173a 0603
          0000030: 3607 1906 1507 ba00 1900 00ab 0000 008b
          0000040: 0000 0002 ffff ffff 0000 008b 0000 0000
          0000050: 0000 0019 1906 3a04 2db6 001a c000 1d3a
          0000060: 0803 3609 1908 1509 ba00 1f00 00ab 0000
          0000070: 0000 0041 0000 0002 ffff ffff 0000 0041
          0000080: 0000 0000 0000 001b 1908 3a05 1904 1220
          0000090: b600 229a 0009 0436 09a7 ffcb b200 2619
          00000a0: 0419 05ba 002c 0000 b600 30a7 0035 b200
          00000b0: 2619 0419 04b6 0036 b600 3aba 003e 0000
          00000c0: b600 30a7 001d b200 2619 0519 06ba 0041
          00000d0: 0000 b600 30a7 000b b200 2612 42b6 0030
          00000e0: a700 114c bb00 4659 2bb6 0048 2bb7 004c
          00000f0: bfb1
        Exception Handler Table:
          bci [39, 42] => handler: 227
          bci [89, 92] => handler: 227
        Stackmap Table:
          append_frame(@9,Object[#18],Integer)
          same_frame(@36)
          full_frame(@50,{Object[#18],Object[#18],Integer,Object[#18],Top,Top,Object[#23],Integer},{})
          same_frame(@84)
          full_frame(@100,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Top,Object[#23],Integer,Object[#29],Integer},{})
          same_frame(@136)
          full_frame(@156,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Object[#29],Object[#23],Integer,Object[#29],Integer},{})
          full_frame(@174,{Object[#18],Object[#18],Integer,Object[#18],Object[#23],Top,Object[#23],Integer,Object[#29],Integer},{})
          full_frame(@198,{Object[#18],Object[#18],Integer,Object[#18],Top,Top,Object[#23],Integer},{})
          full_frame(@216,{Object[#18],Object[#18],Integer},{})
          chop_frame(@224,2)
          same_locals_1_stack_item_frame(@227,Object[#68])
          same_frame(@241)

      | at (#15:1)

      ---------- BEGIN SOURCE ----------
      record MyPair<T1, T2>(T1 first, T2 second) {}

          static void recordInferenceJdk19(MyPair<String, Integer> pair) {
              switch (pair) {
                  case MyPair<String, Integer>(var text, var count) when text.contains("Michael") ->
                          System.out.println(text + " is " + count + " years old");
                  case MyPair<String, Integer>(var text, var count) when count > 5 && count < 10 ->
                          System.out.println("repeated " + text.repeat(count));
                  case MyPair<String, Integer>(var text, var count) -> System.out.println(text + count);
                  default -> System.out.println("PENG");
              }
          }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      jshell> static void recordInferenceJdk19io(MyPair<String, Integer> pair) {
         ...> if (pair instanceof MyPair<String, Integer>(var text, var count) && text.contains("Michael"))
         ...> System.out.println(text + " is " + count + "years old");
         ...> else if (pair instanceof MyPair<String, Integer>(var text, var count) && count > 5 && count < 10)
         ...> System.out.println("repeated " + text.repeat(count));
         ...> else if (pair instanceof MyPair<String, Integer>(var text, var count))
         ...> System.out.println(text + count);
         ...> else
         ...> System.out.println("PENG");
         ...> }
      | Erstellt Methode recordInferenceJdk19io(MyPair<String, Integer>)

      jshell> recordInferenceJdk19io(new MyPair<>("Mike", 7))
      repeated MikeMikeMikeMikeMikeMikeMike

      jshell> recordInferenceJdk19io(new MyPair<>("Michael", 52))
      Michael is 52years old

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

              Created:
              Updated:
              Resolved: