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

Javac generates uncorrect bytecodes when using nested pattern variables

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 17
    • Fix Version/s: 17
    • Component/s: tools
    • Labels:
      None
    • Subcomponent:
    • Resolved In Build:
      b29
    • CPU:
      generic
    • OS:
      generic

      Backports

        Description

        I try the following code when solving the JDK-8267610.

        ```
        class Main {
            String test(Object o) {
                if (o instanceof (CharSequence cs && cs instanceof String s)){
                    return s;
                }
                return null;
            }
        }
        ```

        The javac compiles successfully and generates the following bytecode.

        ```
          java.lang.String test(java.lang.Object);
            descriptor: (Ljava/lang/Object;)Ljava/lang/String;
            flags: (0x0000)
            Code:
              stack=1, locals=4, args_size=2
                 0: aload_1
                 1: instanceof #7 // class java/lang/CharSequence
                 4: ifeq 26
                 7: aload_1
                 8: checkcast #7 // class java/lang/CharSequence
                11: astore_2
                12: aload_1 // <---------- should be `aload_2`
                13: instanceof #9 // class java/lang/String
                16: ifeq 26
                19: aload_1 // <---------- should be `aload_2`
                20: checkcast #9 // class java/lang/String
                23: astore_3
                24: aload_3
                25: areturn
                26: aconst_null
                27: areturn
        ```

        There are two wrong places where I mark "// <---------- should be `aload_2`".

        After fixing JDK-8267610 locally, javac generates the following byte code:

        ```
          java.lang.String test(java.lang.Object);
            descriptor: (Ljava/lang/Object;)Ljava/lang/String;
            flags: (0x0000)
            Code:
              stack=1, locals=4, args_size=2
                 0: aload_1
                 1: instanceof #7 // class java/lang/CharSequence
                 4: ifeq 26
                 7: aload_1
                 8: checkcast #7 // class java/lang/CharSequence
                11: astore_2
                12: aload_2
                13: instanceof #9 // class java/lang/String
                16: ifeq 26
                19: aload_1 // <---------- should be `aload_2`
                20: checkcast #9 // class java/lang/String
                23: astore_3
                24: aload_3
                25: areturn
                26: aconst_null
                27: areturn
        ```

        One wrong byte code is also generated.

        Both JDK-8267610 and this issue are caused by the BindingPattern and BindingSymbol.
        During desugar, especially TransPatterns, we shouldn't make a tree which contains JCBindingPattern or BindingSymbol. So after desugar, the whole AST shouldn't contain JCBindingPattern or BindingSymbol anymore.
        If not, the tree is wrong and the javac may crash or generate wrong bytecode unexpectedly.

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                gli Guoxiong Li
                Reporter:
                gli Guoxiong Li
                Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved: