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

Compiler produces invalid bytecode for method class creation from static method

XMLWordPrintable

    • master
    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      Run the attached source code, and observe an error at runtime: "java.lang.VerifyError: Bad type on operand stack".

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Download the source code and run it with the `java` command.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I would expect a single line to be printed and the terminate to terminate successfully. Or alternatively that the program would not compile (which seems to make more sense to me).
      ACTUAL -
      The program crashes with the following stacktrace:

      Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
      Exception Details:
        Location:
          MainClass$1InnerClass.create(Ljava/lang/String;)LMainClass$1InnerClass; @6: getfield
        Reason:
          Type 'java/lang/String' (current frame, stack[3]) is not assignable to 'MainClass$1InnerClass'
        Current Frame:
          bci: @6
          flags: { }
          locals: { 'java/lang/String' }
          stack: { uninitialized 0, uninitialized 0, 'java/lang/String', 'java/lang/String' }
        Bytecode:
          0000000: bb00 0259 2a2a b400 01b7 001b b0

              at MainClass.main(repro.java:22)

      The error comes from a compiler-inserted `aload` instruction that tries to load the string from the outer method despite being in an inner method.

      ---------- BEGIN SOURCE ----------
      public class MainClass {
          public static void main(String[] args) {
              Object variable = "world";

              class InnerClass {
                  private final String part1;

                  InnerClass(String part1) {
                      this.part1 = part1;
                  }

                  @Override
                  public String toString() {
                      return this.part1 + " " + variable;
                  }

                  static InnerClass create(String part1) {
                      return new InnerClass(part1);
                  }
              }

              System.out.println(InnerClass.create("hello,").toString());
          }
      }
      ---------- END SOURCE ----------

            vromero Vicente Arturo Romero Zaldivar
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: