RFR: 8371309: Diagnostic.getEndPosition can throw an NPE with typical broken code
Archie Cobbs
acobbs at openjdk.org
Fri Nov 14 16:47:03 UTC 2025
On Fri, 14 Nov 2025 08:22:46 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:
> When starting the compiler via API, a `DiagnosticListener` may be provided, to which all reported errors and warnings are reported.
>
> The reported diagnostics are represented by `javax.tools.Diagnostic`, which has (among others) method `getEndPosition`, which requires the end-pos-table to be set in the `DiagnosticSource` object for the given file (see `AbstractLog.sourceMap`). But the end-pos-table is only set after the parse is done:
> https://github.com/openjdk/jdk/blob/167c952bb0fefb5acc9782f4f4474d92097c93f8/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java#L702
>
> There are three problems with this:
> - when a `Diagnostic` is reported by the parser, and the clients code calls `Diagnostic.getEndPosition`, the end-pos-table is not set yet, and the method crashes with an NPE
> - the end-pos-table is never set for implicitly compiled (parsed) files:
> https://github.com/openjdk/jdk/blob/167c952bb0fefb5acc9782f4f4474d92097c93f8/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java#L840
> - when a `Diagnostic` is reported for a tree by the parser, the tree on which the `Diagnostic` appear does not typically have the end position set yet - it is usually set only after the error/warning is reported
>
> All those problems used to be hidden by this check:
> https://github.com/openjdk/jdk/blob/6c48f4ed707bf0b15f9b6098de30db8aae6fa40f/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java#L649
> but that has been removed:
> https://github.com/openjdk/jdk/commit/c793de989facdb532021e1d5ddd01eb0e089b8e6
>
> I have tried to fix this properly, by deferring the errors from the parser to a later point, properly setting the end-pos-table, and handling implicitly parsed files more correctly:
> https://github.com/openjdk/jdk/compare/master...lahodaj:jdk:JDK-8371309b?expand=1
> but this change is a bit involved, and potentially a bit dangerous.
>
> So, for now, I propose to reinstate the null check in `TreeInfo.getEndPos`, to restore the JDK 25 behavior, and attempt to do the better solution later, hopefully earlier in the release cycle.
It's my fault for provoking this issue with the commit you referenced - apologies, that change was overly optimistic. I agree the practical answer for now is to add back the null check.
It makes me wonder if the specified behavior for `Diagnostic.getEndPosition()` was previously being adhered to. It says:
> offset from beginning of file; `NOPOS` if and only if `getPosition()` returns `NOPOS`
It seems like more realistic (and accurate) specification would be:
> offset from beginning of file; `NOPOS` if the ending position is not available
That's a separate question from this PR of course.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/28316#issuecomment-3533652450
More information about the compiler-dev
mailing list