RFR: JDK-8198945: Invalid RuntimeVisibleTypeAnnotations for annotation on anonymous class type parameter

Liam Miller-Cushon cushon at google.com
Fri Jun 29 22:55:30 UTC 2018


Hi,


Please consider this fix for JDK-8198945, which I prepared in collaboration
with wmdietl.


bug: https://bugs.openjdk.java.net/browse/JDK-8198945

webrev: http://cr.openjdk.java.net/~cushon/8198945/webrev.00/


The issue involves annotations on the type of an anonymous class
declaration.


Consider e.g.:


```

import java.lang.annotation.*;

class Test {

  @Target(ElementType.TYPE_USE) @interface TA {}

  @Target(ElementType.TYPE_USE) @interface TB {}

  interface I<T> {}


  void f() {

    new @TA I<@TB Object>() {};

  }

}

```


Note that the use of `I` in the anonymous class declaration corresponds to
the supertype of the declared anonymous class, not the type of the
anonymous class Test$1.


With javac 11-ea+19 the annotations are attached to the supertype of
Test$1, as expected:


$ javap -v 'Test$1'

...

RuntimeInvisibleTypeAnnotations:

  0: #21(): CLASS_EXTENDS, type_index=0, location=[TYPE_ARGUMENT(0)]

    Test$TB

  1: #24(): CLASS_EXTENDS, type_index=0

    Test$TA


However the annotations also appear at the enclosing method declaration:


$ javap -v Test

...

  void f();

    descriptor: ()V

    flags: (0x0000)

    Code:

      stack=3, locals=1, args_size=1

         0: new           #2                  // class Test$1

         3: dup

         4: aload_0

         5: invokespecial #3                  // Method
Test$1."<init>":(LTest;)V

...

      RuntimeInvisibleTypeAnnotations:

        0: #19(): NEW, offset=0

          Test$TB

        1: #20(): NEW, offset=0

          Test$TA

    RuntimeInvisibleTypeAnnotations:

      0: #19(): CLASS_EXTENDS, type_index=0, location=[TYPE_ARGUMENT(0)]

        Test$TB


The handling of @TB in particular is clearly incorrect:

* @TB appears with a `NEW` type path that leads to the top-level type of
the 'new' expression, even though @TB appeared on a type argument of that
type and not at the top level.

* @TB also appears on 'f' with a `CLASS_EXTENDS` path and no bytecode
offset, which does not provide enough information to associate it with the
annotated location.


The handling of @TA is also questionable. It makes some sense to use the
same type path for an annotation on the type of an anonymous class
declaration as the type of a regular 'new' expression. However that results
in the same use of @TA appearing twice in bytecode, and conflates the type
of the anonymous class with its supertype.


I think it is more correct to only emit @TA as a `CLASS_EXTENDS` annotation
on Test$1, and not include a copy of it at the enclosing method.


Thanks,

Liam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20180629/23f1999d/attachment.html>


More information about the compiler-dev mailing list