RFR: 8334488: Improve error for illegal early access from nested class

Maurizio Cimadamore mcimadamore at openjdk.org
Tue Jun 18 23:13:10 UTC 2024


On Tue, 18 Jun 2024 16:12:55 GMT, Archie Cobbs <acobbs at openjdk.org> wrote:

> Consider this class:
> 
> class CtorPrologueBugTest {
>     int x;
>     CtorPrologueBugTest() {
>         this(new Object() {
>             { System.out.println(x); }
>         });
>     }
>     CtorPrologueBugTest(Object obj) {
>     }
> }
> 
> Prior to [JDK-8194743](https://bugs.openjdk.org/browse/JDK-8194743), it resulted in this error, generated by `Attr.java`:
> 
> CtorPrologueBugTest.java:5: error: cannot reference x before supertype constructor has been called
>             { System.out.println(x); }
>                                  ^
> 
> After [JDK-8194743](https://bugs.openjdk.org/browse/JDK-8194743), it resulted in this different error, generated later in the compilation process by `Lower.java`:
> 
> CtorPrologueBugTest.java:5: error: no enclosing instance of type CtorPrologueBugTest is in scope
>             { System.out.println(x); }
>                                  ^
> 
> There are two problems with this change in behavior:
> 
> 1. Such errors should be detected by `Attr.java`, not `Lower.java`, so that IDE's that only display errors generated by earlier compilation phases will show them.
> 1. The wording change in the error message is technically incorrect: `x` is in scope, it's just not yet accessible.
> 
> This change in behavior reflects an underlying logic bug, which is that `Attr::visitClassDef` is setting `ctorPrologue = false` on the containing class' environment, instead of the nested class' environment. As a result, when `Attr` descends into the nested class and then finds the `x` symbol in the containing class, it has "forgotten" that it is in an early construction context for `CtorPrologueBugTest` and fails to report the error at that point as it should.
> 
> This patch fixes this glitch to the error is detected earlier in the compilation process by `Attr` and is reported with the more correct verbiage.
> 
> Thanks to @mcimadamore for pointing out the mistake.

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java line 212:

> 210:                                    // when annotations have been processed
> 211:         localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree);
> 212:         localEnv.info.ctorPrologue = false;

In my local experiments I added this to `Attr::attribClass`, but this was the other alternative, and, on a second look it probably looks like the cleanest approach.

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

PR Review Comment: https://git.openjdk.org/jdk/pull/19773#discussion_r1645202046


More information about the compiler-dev mailing list