RFR: 8194743: Compiler implementation for Statements before super() [v16]
Maurizio Cimadamore
mcimadamore at openjdk.org
Mon Sep 25 17:56:19 UTC 2023
On Mon, 25 Sep 2023 16:04:09 GMT, Archie Cobbs <acobbs at openjdk.org> wrote:
>> This is a first draft of a patch for JEP 447.
>>
>> Summary of changes:
>>
>> 1. Track when we're within a constructor "prologue" via new flag `AttrContext.ctorPrologue`
>> 1. Add checks for illegal early access to `this` in constructor prologues, and update existing checks to distinguish between static context vs. constructor prologue context
>> 1. Verify allowed placement of `super()`/`this()` calls via new method `Check.checkSuperInitCalls()`
>> 1. Remove/refactor assumptions in several places that `super()`/`this()` was always the first statement
>>
>> The changes in `Flow.java` are an example of <span>#</span>4. `Flow.FlowAnalyzer` checks for uncaught checked exceptions. For initializer blocks, this was previously done by requiring that any checked exceptions thrown be declared as thrown by all constructors containing `super()`. This list of checked exceptions was being pre-calculated before recursing into the initial constructors. This worked because initializer blocks were executed at the beginning of each initial constructor right after `super()` is called.
>>
>> Now initializer blocks are traversed as each `super()` invocation is encountered, reflecting what actually happens at runtime. Similarly, final fields are marked as DA after encountering `this()`, not automatically at the beginning of those constructors. These changes produce equivalent checks, but are compatible with the new flexibility of placement of `super()`/`this()` as well as possible future changes that could occur along these same lines.
>
> Archie Cobbs has updated the pull request incrementally with one additional commit since the last revision:
>
> Have RefBeforeCtorCalledError extend StaticError and customize debug strings.
Overall, this is a very good patch. Not only it adds a new feature (which I found myself reaching for several times), but it also does so by consolidating a bunch of logic in the compiler code. Well done!
src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties line 238:
> 236: # 0: name
> 237: compiler.err.call.must.only.appear.in.ctor=\
> 238: calls to {0}() may only appear within constructors
Note that super()/this() in the JLS lingo is called "explicit constructor invocation".
src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties line 245:
> 243:
> 244: # 0: name
> 245: compiler.err.calls.not.allowed.here=\
The compiler message key seems overly general. maybe `constructor.call.not.allowed.here` ?
src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties line 250:
> 248: # 0: name
> 249: compiler.err.return.before.superclass.initialized=\
> 250: ''return'' not allowed prior to {0}()
We have no other match in this file for `prior to`, but we do have matches for `before`. I suggest using the latter for a more consistent style.
-------------
PR Review: https://git.openjdk.org/jdk/pull/13656#pullrequestreview-1642717335
PR Review Comment: https://git.openjdk.org/jdk/pull/13656#discussion_r1336211699
PR Review Comment: https://git.openjdk.org/jdk/pull/13656#discussion_r1336213538
PR Review Comment: https://git.openjdk.org/jdk/pull/13656#discussion_r1336214539
More information about the compiler-dev
mailing list