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

javac creates an Element whose getEnclosingElement() does not enclose it

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P4
    • tbd
    • 18, 19
    • tools
    • I reproduced under this environment:

      Linux xps8940 5.15.0-47-generic #51-Ubuntu SMP Thu Aug 11 07:51:15 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

    • 18
    • generic
    • generic

    Description

      javac 18 and 19 can produce an element for which this assertion fails:

        ExecutableElement myMethod = ...;
        TypeElement enclosingType = (TypeElement) myMethod.getEnclosingElement();
        assert enclosingType.getEnclosedElements().contains(myMethod)

      javac 8, 11, and 17 do satisfy the assertion.

      Here is code to reproduce the problem:

        interface CallInDefaultImplementation {
          public default String className() {
            return getClass().getSimpleName();
          }
        }

      The ExecutableElement for `getClass()` in the body of `className()` has an enclosing element of CallInDefaultImplementation, which violates the assertion.
      In javac before version 18, the ExecutableElement for `getClass()` has an enclosing element of Object, which satisfies the assertion.

      I have only observed the problem within the body of a default method implementation (in an interface), when calling methods that are defined on Object such as getClass() and hashCode().

      This violation of an expected invariant harms tools that use APIs in javax.lang.model.element. I noticed the problem because the Checker Framework does not run properly under JDK 18, though it works fine under JDK 17 and earlier. Therefore, I consider this a regression.

      This problem doesn't seem to harm javac. I see that javac's bytecode generation strategy has changed between javac 17 and javac 18. javac 18 and later uses an invokeinterface bytecode to call getClass(), whereas javac 17 and earlier used invokevirtual. With invokeinterface, it isn't necessary for the ExecutableElement to have a proper enclosing element. However, I see no harm in it.

      Attachments

        Issue Links

          Activity

            People

              jlahoda Jan Lahoda
              mernst Michael Ernst
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: