javac generates incorrect class_index in constant pool

XMLWordPrintable

    • Type: Bug
    • Resolution: Not an Issue
    • Priority: P4
    • None
    • Affects Version/s: 1.4.0
    • Component/s: tools
    • x86
    • windows_2000



      Name: nt126004 Date: 05/22/2002


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)


      FULL OPERATING SYSTEM VERSION :

      Microsoft Windows 2000 [Version 5.00.2195] with SP2

      ADDITIONAL OPERATING SYSTEMS :

      All



      A DESCRIPTION OF THE PROBLEM :
      Under certain circumstances javac generates class_index
      values in a constant pool entry for a MethodRef or FieldRef
      that refers to the current class instead of the super class
      where the field or method was defined.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Write the following two classes:

      public class Base {
        protected static boolean assertEnabled = true;
        protected static void doAssert(boolean cond, String msg) {
          if (!assertEnabled) return;
          if (cond) return;
          throw new RuntimeException("AssertionFailure: " + msg);
        }
      }

      public class Derived extends Base {
        static {
           Derived.assertEnabled = false;
        }
        public void foo(int x) {
          Derived.doAssert(x > 0, "not >0");
        }
      }

      2. Compile: javac Base.java Derived.java
      3. Examine the class file for Derived using a suitable tool
         that shows the constant pool.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      The constant pool shows a MethodRef for doAssert with a
      class_index that refers to Derived, and similarly a
      FieldRef for assertEnabled with a class_index that refers
      to Derived.

      According to the JLS, Section 4.4.2, the class_index is
      supposed to refer to the class or interface that contains
      the declaration of the field or method. In this case that
      should be Base not Derived.

      If we change the source code so that the super method and
      field are accessed without qualification (ie. doAssert
      instead of Derived.doAssert) then the constant pool index
      is generated correctly.

      Further, if we compile the given code using "-target 1.1"
      then again the correct index is generated.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class Base {
        protected static boolean assertEnabled = true;
        protected static void doAssert(boolean cond, String msg) {
          if (!assertEnabled) return;
          if (cond) return;
          throw new RuntimeException("AssertionFailure: " + msg);
        }
      }

      public class Derived extends Base {
        static {
           Derived.assertEnabled = false;
        }
        public void foo(int x) {
          Derived.doAssert(x > 0, "not >0");
        }
      }

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

      CUSTOMER WORKAROUND :
      compile using -target 1.1
      (Review ID: 146875)
      ======================================================================

            Assignee:
            Neal Gafter (Inactive)
            Reporter:
            Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: