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