RFR: 8346751: Internal java compiler error with type annotations in constants expression in constant fields
Vicente Romero
vromero at openjdk.org
Mon Jan 13 15:56:46 UTC 2025
On Fri, 10 Jan 2025 08:11:56 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:
> Consider code like:
>
> import java.lang.annotation.*;
> public class Decl {
> String VALUE = (@Nullable String) "";
> }
> @Retention(RetentionPolicy.RUNTIME)
> @Target({ ElementType.TYPE_USE })
> @interface Nullable {}
>
>
> When processing this code, when `Attr.visitVarDef` is called for the field, it will first call `Annotate.queueScanTreeAndTypeAnnotate` on the initializer expression, which will find and attribute type annotations. Then the initializer is attributed, and eventually `Annotate.annotateTypeSecondStage` is called on the annotated type (`@Nullable String`). This second stage depends on the type annotations being already attributed. This works OK.
>
> The problem appears when the code like changed to be like:
>
> import java.lang.annotation.*;
> @SuppressWarnings(Decl.VALUE)
> public class Decl {
> public static final @Nullable String VALUE = (@Nullable String) "";
> }
> @Retention(RetentionPolicy.RUNTIME)
> @Target({ ElementType.TYPE_USE })
> @interface Nullable {}
>
>
> In this code, the field is a constant, and it is used from the annotation before `Attr.visitVarDef` is called on the constant. This will trigger attribution of the constant initializer (`Attr.attribLazyConstantValue`), which will trigger the `Annotate.annotateTypeSecondStage` on the annotated type, but `Annotate.queueScanTreeAndTypeAnnotate` was not yet called on the initializer, and so the type annotations are not attributed yet, and javac crashes with an exception like:
>
>
> java.lang.AssertionError
> at jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155)
> at jdk.compiler/com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:62)
> at jdk.compiler/com.sun.tools.javac.comp.Annotate.fromAnnotations(Annotate.java:167)
> at jdk.compiler/com.sun.tools.javac.comp.Annotate.lambda$annotateTypeSecondStage$0(Annotate.java:1065)
> at jdk.compiler/com.sun.tools.javac.comp.Annotate.flush(Annotate.java:194)
> 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:1820)
> at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1080)
> at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:949)
> at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
> at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImp...
looks good
-------------
Marked as reviewed by vromero (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/23029#pullrequestreview-2547081611
More information about the compiler-dev
mailing list