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

"Detected branch target out of bytecode range" when transforming class

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 25
    • core-libs

      ADDITIONAL SYSTEM INFORMATION :
      java version "25" 2025-09-16 LTS
      Java(TM) SE Runtime Environment (build 25+37-LTS-3491)
      Java HotSpot(TM) 64-Bit Server VM (build 25+37-LTS-3491, mixed mode, sharing)

      A DESCRIPTION OF THE PROBLEM :

      When using the Java java.lang.classfile API to construct and parse class files that contain branch instructions (such as ifge with labels), a bug surfaces in which the labels (used as branch targets) may remain uninflated after parsing with ClassFile.of().parse(byteCode). As a result, any subsequent processing or copying of the parsed CodeModel such as emitting a new class file using with(cde) can trigger the following error:

      ---------- BEGIN SOURCE ----------
      import java.lang.classfile.*;
      import java.lang.constant.*;

      class ClassFileBug {
          public static void main(String[] args) {
              // (1) Build a trivial class with a branch:
              // equivalent to:
              // class TestClass {
              // static int clamp(int x) {
              // if (x < 0) return 0;
              // return x;
              // }
              // }
              ClassDesc className = ClassDesc.of("TestClass");
              String methodName = "clamp";
              MethodTypeDesc methodType = MethodTypeDesc.of(ConstantDescs.CD_int, ConstantDescs.CD_int);
              int methodFlags = ClassFile.ACC_STATIC;
              
              byte[] byteCode = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(className, clb -> {
                  clb.withMethodBody(methodName, methodType, methodFlags, cdb -> {
                      var label = cdb.newLabel();
                      // if (x < 0)
                      cdb.iload(0);
                      cdb.ifge(label);
                      // return 0
                      cdb.iconst_0();
                      cdb.ireturn();
                      // return x
                      cdb.labelBinding(label);
                      cdb.iload(0);
                      cdb.ireturn();
                  });
              });
              
              // (2) Load the CodeModel back in
              ClassModel classModel = ClassFile.of().parse(byteCode);
              CodeModel methodCode = classModel.methods().getFirst().code().get();
              
              // (3) Try to use the code in a new class; it blows up:
              // "Detected branch target out of bytecode range at bytecode offset 1 of method clamp(int)
              // 0000: 1a 9c ff fe 03 ac 1a ac"
              ClassFile.of().build(className, clb -> {
                  clb.withMethodBody(methodName, methodType, methodFlags, cdb -> {
                      //methodCode.toDebugString(); // ##### <-- uncomment this line and the exception disappears #####
                      for (CodeElement cde : methodCode) {
                          cdb.with(cde);
                      }
                  });
              });
              
              System.out.println("Success");
          }
      }
      ---------- END SOURCE ----------


      This issue does not occur if the debugging method toDebugString() is called on the CodeModel before reuse, suggesting that the process of inflating labels is incorrectly deferred until such a call.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: