RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v3]

Archie L. Cobbs duke at openjdk.org
Thu Nov 17 19:11:18 UTC 2022


> This patch is both a minor optimization and a fix for JDK-7176515.
> 
> JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar".
> 
> The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later.
> 
> Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug.
> 
> This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table.
> 
> This results in two improvements:
> * It avoids building the lookup table for switches on self
> * It fixes JDK-7176515 as stated
> 
> Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out).
> 
> So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it.
> 
> Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled.

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-7176515
 - Give test a better name and don't rely on assertions being enabled.
 - Skip enum switch lookup tables when compiling the enum switch class.

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

Changes:
  - all: https://git.openjdk.org/jdk/pull/10797/files
  - new: https://git.openjdk.org/jdk/pull/10797/files/8cd5b49c..b5da18df

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=02
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=01-02

  Stats: 232655 lines in 2313 files changed: 113387 ins; 82545 del; 36723 mod
  Patch: https://git.openjdk.org/jdk/pull/10797.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/10797/head:pull/10797

PR: https://git.openjdk.org/jdk/pull/10797


More information about the compiler-dev mailing list