RFR: 8184444: The compiler error "variable not initialized in the default constructor" is not apt in case of static final variables [v3]
Archie L. Cobbs
duke at openjdk.org
Mon Dec 19 15:44:39 UTC 2022
> This bug causes this class:
>
> class StaticFinalInit {
> static final int foo;
> }
>
> to fail to compile as it should but with a confusing error message:
>
> StaticFinalInit.java:2: error: variable foo not initialized in the default constructor
> static final int foo;
> ^
>
> In another variant, if there is a non-default constructor:
>
> class StaticFinalInit {
> static final int foo;
> StaticFinalInit() { }
> }
>
> the compiler gives the right error message but shows the wrong source code location:
>
> StaticFinalInit.java:3: error: variable foo might not have been initialized
> StaticFinalInit() { }
> ^
>
> This behavior is a side-effect of the roundabout way we currently check for definite assignment of static final fields.
>
> When recursing into a class definition in `Flow.AssignAnalyzer`, we first initialize DA/DU analysis for static fields, and then recurse on the static initializers to pick up static field assignments. However, we don't then check for definite assignment of static final fields. Instead, we proceed with the analysis, and then later, whenever we visit an initial constructor (i.e., one that invokes `super()` instead of `this()`), we check for definite assignment of both static final and instance final fields.
>
> This works because every class has at least one initial constructor, so static fields will always get checked at least once. Of course, it also results in doing some redundant work (if there are multiple initial constructors) and it generates the wrong error message and/or source code position.
>
> This patch adds a check for definite assignment of static final fields (with the appropriate error message) after we recurse on the static initializers, and it filters out static fields from the checks being done in initial constructors. It also updates a couple of existing unit tests that were expecting the wrong source code position.
>
> The two examples above now both generate this error message:
>
> StaticFinalInit.java:2: error: variable foo might not have been initialized
> static final int foo;
> ^
Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision:
- Merge branch 'master' into JDK-8184444
- Merge branch 'master' into JDK-8184444
- Fix confusing error message for uninitialized static final fields.
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/10896/files
- new: https://git.openjdk.org/jdk/pull/10896/files/1e6594d2..d9ef373f
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=10896&range=02
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=10896&range=01-02
Stats: 136482 lines in 2312 files changed: 69468 ins; 45399 del; 21615 mod
Patch: https://git.openjdk.org/jdk/pull/10896.diff
Fetch: git fetch https://git.openjdk.org/jdk pull/10896/head:pull/10896
PR: https://git.openjdk.org/jdk/pull/10896
More information about the compiler-dev
mailing list