RFR: JDK-8247334: Trees.getScope crashes for annotated local records
Vicente Romero
vicente.romero at oracle.com
Thu Jun 11 13:56:33 UTC 2020
looks good,
Thanks,
Vicente
On 6/10/20 4:07 PM, Jan Lahoda wrote:
> 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