RFR: 8337976: Insufficient error recovery in parser for switch inside class body
Jan Lahoda
jlahoda at openjdk.org
Fri Aug 9 15:03:03 UTC 2024
Consider this code:
public class T9999999 {
switch (0) { default: }
}
When trying to compile this, javac crashes:
$ .../jdk-22/bin/javac -XDdev /tmp/T9999999.java
/tmp/T9999999.java:2: error: switch expression does not have any result expressions
switch (0) { default: } f;
^
1 error
An exception has occurred in the compiler (22.0.1-internal). Please file a bug against the Java compiler via the Java bug reporting page (https://bugreport.java.com/) after checking the Bug Database (https://bugs.java.com/) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
java.lang.AssertionError: Unexpected tree: switch (0) {
default:
} with kind: SWITCH_EXPRESSION within: switch (0) {
default:
} with kind: SWITCH_EXPRESSION
at jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:162)
at jdk.compiler/com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.validateAnnotatedType(Attr.java:5881)
at jdk.compiler/com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitVarDef(Attr.java:5727)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:1022)
at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at jdk.compiler/com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitClassDef(Attr.java:5780)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:814)
at jdk.compiler/com.sun.tools.javac.comp.Attr.validateTypeAnnotations(Attr.java:5677)
at jdk.compiler/com.sun.tools.javac.code.TypeAnnotations.lambda$validateTypeAnnotationsSignatures$1(TypeAnnotations.java:144)
at jdk.compiler/com.sun.tools.javac.comp.Annotate.flush(Annotate.java:200)
at jdk.compiler/com.sun.tools.javac.comp.Annotate.unblockAnnotations(Annotate.java:144)
at jdk.compiler/com.sun.tools.javac.comp.Annotate.enterDone(Annotate.java:157)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterDone(JavaCompiler.java:1827)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1081)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:947)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:66)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:52)
printing javac parameters to: /home/jlahoda/src/jdk/jdk/javac.20240809_163551.args
The problem is that while parsing a the class body, javac will try to parse a type (as a type of a field or method), but finds the switch. Which will get parsed as an expression, and used as the type of the field `f`. This then crashes type annotation validation, but generally does not make much sense.
The proposal here is to check if there's a token that inevitably is a start of a statement used inside a class (or interface, enum, annotation type or record), and if yes, parse the input as a statement.
As a result, the parser tolerates statements inside a class body. The statement's tree is wrapped inside an `ErroneousTree`, so that it is obvious it is not a correct AST.
The attribution is also tweaked a bit to handle the augmented AST better.
-------------
Commit messages:
- Cleanup.
- Cleanup/reducing scope
- Fixing tests.
- 8337976: Insufficient error recovery in parser for switch inside class body, and missing name in parameterized type
Changes: https://git.openjdk.org/jdk/pull/20526/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=20526&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8337976
Stats: 128 lines in 9 files changed: 118 ins; 1 del; 9 mod
Patch: https://git.openjdk.org/jdk/pull/20526.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/20526/head:pull/20526
PR: https://git.openjdk.org/jdk/pull/20526
More information about the compiler-dev
mailing list