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

javac generates incorrect class_index for static ref by simple name

    XMLWordPrintable

    Details

    • Subcomponent:
    • Resolved In Build:
      mantis
    • CPU:
      x86
    • OS:
      windows_2000
    • Verification:
      Verified

      Description



      Name: nt126004 Date: 06/20/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 :
      The JLS 2ed, Section 13.1, changed the rules by which
      static references are stored in the binary class file.
      Here are the rules for field accesses, with similar rules
      for method references:

      >>>
      Given a legal expression denoting a field access in a class
      C, referencing a field named f declared in a (possibly
      distinct) class or interface D, we define the qualifying
      type of the field reference as follows:
      - If the expression is of the form Primary.f then the
        compile-time type of Primary is the qualifying type of
        the reference.
      - If the expression is of the form super.f then the
        superclass of C is the qualifying type of the reference.
      - If the expression is of the form X.super.f then the
        superclass of X is the qualifying type of the reference.
      - If the reference is of the form X.f, where X denotes a
        class or interface, then the class or interface denoted
        by X is the qualifying type of the reference
      - If the expression is referenced by a simple name, then if
        f is a member of the current class or interface, C, then
        let T be C. Otherwise, let T be the lexically enclosing
        class of which f is a member. T is the qualifying type of
        the reference.
      >>>

      However, when a simple name is used javac exhibits a bug,
      by using the type of the class where the field/method is
      declared as the qualifying type, rather than the current
      class of which the field/method is an inherited member.


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

      public class Base {
        protected static boolean x = true;
        protected static void print() {
           System.out.println("Base.print");
        }
      }
      public class Derived extends Base {

        {
           Derived.x = false;
           this.x = false;
           x = false;

           Derived.print();
           this.print();
           print();
        }

      }

      2. Compile them

      3. Examine the constant pool entries for class Derived

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      According to JLS 13.1 all three references to x and print
      should have the qualifying type of Derived:

      Derived.* => Derived because it is the form X.f and X is a
      class type.

      this.* => Derived because it is the form Primary.f and the
      compile time type of the primary is Derived

      * => Derived because it is a simple name f and f is a
      member of the current class, and so the qualifying type is
      the current class.

      However, upon examination of the constant pool we find that
      in this last case when the simple name is used,
      the compiler has generated the class_index for Base, the
      class in which the field/method is declared, not Derived,
      the class in which it is a member.

      This is incorrect according to the rules.



      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class Base {
        protected static boolean x = true;
        protected static void print() { System.out.println("Base.print"); }
      }

      public class Derived extends Base {

        {
           Derived.x = false;
           this.x = false;
           x = false;

           Derived.print();
           this.print();
           print();
        }

      }
      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Always use a fully qualified name to refer to static
      fields/methods.

      Or more strongly, always use the name of the class in which
      the field or method is declared to access the field or
      method. This avoids potential problems that the new rules
      allow, by preventing an intervening super class from
      redefining the static field/method that the derived class
      thinks it is accessing.
      (Review ID: 153810)
      ======================================================================

        Attachments

          Activity

            People

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

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: