RFR 8169345: javac crash when local from enclosing context is captured multiple times

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Oct 6 14:39:21 UTC 2017

this patch fixes an issue regarding how Lower handles captured variables 
from enclosing scopes. Quoting from my analysis in JBS [1]:

class Main {
     void test () {
         Object o = new Object();
         class Local1 {
             Object test1() { return o; }
         class Local2 {
              void test2() {
                   Object o = new Object();
                   class Local3 extends Local1 {
                       Object test3() { return o; }

Here, class Local3 captures 'o' from:

* Main::test (this capture is necessary, as the superclass constructor 
(for Local1) will need to take that 'b'
* Local2::test2 (this capture is necessary as that's the variable 
referenced to by the Local3::test3 method)

This ends up breaking many invariants inside Lower, as:

* Lower represents all captured variables using a simple encoding such 
as 'val' $ 'varname' - meaning that both captured variables above end up 
as 'val$o'. This will cause issues when looking up the variable - which 
is currently done with a named scope lookup (find first).

* Lower.initField assumes that there's only one (synthetic) parameter 
named 'val$o' in the lowered constructor declaration and it also assumes 
that there's only one (synthetic) field in the local with the same name. 
This correspondency allows Lower to generate the synthetic field 
initializer by relying on scope properties.

Here's the webrev:


Note - this has been briefly discussed in [2].


[1] - https://bugs.openjdk.java.net/browse/JDK-8169345
[2] - 

More information about the compiler-dev mailing list