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 

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:

Full webrev:

What do you think?


> 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