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