RFR: 8322882: Null pointer error when compiling Static initializer in a local class

Maurizio Cimadamore mcimadamore at openjdk.org
Mon Jun 17 21:25:09 UTC 2024


On Mon, 17 Jun 2024 17:23:03 GMT, Archie Cobbs <acobbs at openjdk.org> wrote:

> A local class can capture a free variable from its enclosing scope. The variable's value is passed to the local class constructor via a synthetic constructor parameter, and then stored in a synthetic proxy field in the local class. Therefore, at any point at which such a local class is instantiated, it must also be possible to access the captured free variable's value so it can be passed to the constructor.
> 
> The compiler was incorrectly assuming that within the local class itself, this would always be the case, because of the existence of the synthetic proxy field. Prior to JDK 16, local classes were not allowed to have static methods, so this was a safe assumption. However, that assumption is no longer safe, and violating results in a `NullPointerException`, for example with this class:
> 
> 
> class LocalFreeVarStaticInstantiate {
>     static void foo(Object there) {
>         class Local {
>             {
>                 there.hashCode();
>             }
>             static {
>                 new Local();    // can't get there from here
>             }
>         }
>     }
> }
> 
> 
> This patch adds the missing check for the situation where access to a proxy variable instance field is required for a synthetic constructor parameter, but the instantiation is occurring within a static method of the class containing the field and so the field can't be accessed.
> 
> **Note:** With this change, the following test fails to compile until Maurizio's refactoring relating to lambda's and outer instances (see "javac-pre-capture" Jira bug label) has been applied:
> 
> * `test/langtools/tools/javac/lambda/T8209407/VerifierErrorInnerPlusLambda.java`

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java line 1660:

> 1658:             Symbol proxy = proxies.get(v);
> 1659:             if (proxy != null && proxy.owner == currentClass && currentMethodSym.isStatic())
> 1660:                 log.error(pos, Errors.NonStaticCantBeRef(Kinds.kindName(v), v));

we should never issue errors in Lower (unless for sanity checks). Note that most IDEs runs javac in attribution-only mode, so these errors are not reported. It seems to be that an Attr check is missing here, and this is actually related to the comment I made here:

https://github.com/openjdk/jdk/pull/19705#issuecomment-2174411126

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/19754#discussion_r1643444611


More information about the compiler-dev mailing list