RFR: JDK-8247334: Trees.getScope crashes for annotated local records
Jan Lahoda
jan.lahoda at oracle.com
Wed Jun 10 20:07:15 UTC 2020
Hi Vicente,
On 10. 06. 20 19:46, Vicente Romero wrote:
> Hi,
>
> Sorry I hit the send button too fast. Why is this only happening to
> local records? in any case could you please add a similar test for a non
Thanks for the comment.
I don't think this can happen for records that are not local, because
the scopes are computed differently - for code inside method bodies (and
variable initializers), a copy of the code is created and re-attributed;
for other points in the program, either an existing scope (Env) is used,
(Enter.getClassEnv for classes), or a scope is synthetized without
re-attributing the code, like for methods MemberEnter.getMethodEnv, or
Enter.getTopLevelEnv.
I've added another test case for top-level record (the content of the
resulting scope is a little different, which is due to the differences
in the scope construction, and is the same for classes).
Delta webrev:
http://cr.openjdk.java.net/~jlahoda/8247334/webrev.delta.00-01/
Full webrev:
http://cr.openjdk.java.net/~jlahoda/8247334/webrev.01/
What do you think?
Thanks,
Jan
> local record just to cover it?
>
> Thanks,
> Vicente
>
> On 6/10/20 12:24 PM, Jan Lahoda wrote:
>> Hi,
>>
>> Consider code like this:
>> ---
>> class Test {
>> void t() {
>> record R(@Annotation int i) {}
>> }
>> }
>> @interface Annotation {}
>> ---
>>
>> Calling Trees.getScope for a TreePath pointing at @Annotation in
>> "@Annotation int i" will crash with an exception.
>>
>> The reason is that when the class is first attributed, a synthetic
>> canonical constructor is created for the record. And when the scope is
>> being computed, a copy of the method's body is created (including the
>> synthetic constructor), and re-attributed. And, since this is a
>> record, the constructors are entered first, then a default constructor
>> is possibly created, and then members not entered in the first phase
>> are entered. But the detection of these "other members" fails to
>> detect the default constructor was already entered in the first phase,
>> and as a consequence this default constructor is entered twice, which
>> ultimately leads to the exception.
>>
>> The proposed solution is to simply keep track if a constructor has
>> been added and avoid entering any constructor except the added one
>> during the second stage.
>>
>> I was trying other fix directions, but those typically changed the
>> order of members, either in Element.getEnclosedElements() or in the
>> classfile, which seemed inappropriate for this fix.
>>
>> Proposed webrev:
>> http://cr.openjdk.java.net/~jlahoda/8247334/webrev.00/
>>
>> JBS:
>> https://bugs.openjdk.java.net/browse/JDK-8247334
>>
>> How does this look?
>>
>> Thanks!
>> Jan
>>
>
More information about the compiler-dev
mailing list