RFR: 8361445: javac crashes on unresolvable constant in @SuppressWarnings
Jan Lahoda
jlahoda at openjdk.org
Mon Jul 7 08:30:41 UTC 2025
On Sun, 6 Jul 2025 17:17:07 GMT, ExE Boss <duke at openjdk.org> wrote:
>> Consider this code:
>>
>> @SuppressWarnings(CONST)
>> public class Ann {
>> public static final String CONST = "";
>> }
>>
>>
>> javac will crash attempting to compile it:
>>
>> $ javac -XDdev /tmp/Ann.java
>> /tmp/Ann.java:1: error: cannot find symbol
>> @SuppressWarnings(CONST)
>> ^
>> symbol: variable CONST
>> 1 error
>> An exception has occurred in the compiler (26-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.ClassCastException: class com.sun.tools.javac.code.Attribute$Error cannot be cast to class com.sun.tools.javac.code.Attribute$Constant (com.sun.tools.javac.code.Attribute$Error and com.sun.tools.javac.code.Attribute$Constant are in module jdk.compiler of loader 'app')
>> at jdk.compiler/com.sun.tools.javac.code.Lint.suppressionsFrom(Lint.java:533)
>> ...
>>
>>
>> The reason is that the unresolvable constant will be `Attribute.Error`, not `Attribute.Constant`, and there's an unguarded cast. The proposal herein is to improve error recovery by ignoring non-constant annotation attributes in `Lint.suppressionsFrom`. Such erroneous cases should have already been reported as compile-time errors anyway.
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java line 538:
>
>> 536: .flatMap(LintCategory::get)
>> 537: .filter(lc -> lc.annotationSuppression)
>> 538: .ifPresent(result::add);
>
> It might be better to do the following, which also fixes the non‑`String` case:
> Suggestion:
>
> if (value instanceof Attribute.Constant c && c.value instanceof String s) {
> LintCategory.get(s)
> .filter(lc -> lc.annotationSuppression)
> .ifPresent(result::add);
> }
Is there a reason to believe the non-`String` case is not covered by the current code? In the test, there is `testSuppressWarningsErroneousAttribute2` which shows the current code works for non-`String` constant of type `int`, is there a case we can add to the tests showing the current code not working?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/26142#discussion_r2189353976
More information about the compiler-dev
mailing list