diff options
author | David Malcolm <dmalcolm@redhat.com> | 2024-05-09 13:09:33 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-05-09 13:09:33 -0400 |
commit | b7a2697733d19a093cbdd0e200ffce069a4bc812 (patch) | |
tree | bd11de3beea4900ad0100cd293523b7ab1dffea5 | |
parent | 2a6f99aef7c8522471967b171180d9ba4136da90 (diff) | |
download | gcc-b7a2697733d19a093cbdd0e200ffce069a4bc812.zip gcc-b7a2697733d19a093cbdd0e200ffce069a4bc812.tar.gz gcc-b7a2697733d19a093cbdd0e200ffce069a4bc812.tar.bz2 |
diagnostics: fix corrupt json/SARIF on stderr [PR114348]
Various values of -fdiagnostics-format= request machine-readable output
on stderr, using JSON, but in various places we use fnotice to write
free-form text to stderr, such as "compilation terminated", leading to
corrupt JSON.
Fix by having fnotice skip the output for such cases.
Backported from r14-9554-g0bf99b1b7eda2f (using a variable rather
than a vfunc of class diagnostic_output_format, since the latter
was added in gcc 14)
gcc/ChangeLog:
PR middle-end/114348
* diagnostic.cc (output_format): New variable.
(fnotice): Bail out if the user requested one of the
machine-readable diagnostic output formats on stderr.
(diagnostic_output_format_init): Set output_format.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r-- | gcc/diagnostic.cc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index 0f09308..a3d84cf 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -2175,6 +2175,9 @@ internal_error_no_backtrace (const char *gmsgid, ...) gcc_unreachable (); } + +static enum diagnostics_output_format output_format; + /* Special case error functions. Most are implemented in terms of the above, or should be. */ @@ -2183,6 +2186,25 @@ internal_error_no_backtrace (const char *gmsgid, ...) void fnotice (FILE *file, const char *cmsgid, ...) { + /* If the user requested one of the machine-readable diagnostic output + formats on stderr (e.g. -fdiagnostics-format=sarif-stderr), then + emitting free-form text on stderr will lead to corrupt output. + Skip the message for such cases. */ + if (file == stderr && global_dc) + switch (output_format) + { + default: + gcc_unreachable (); + case DIAGNOSTICS_OUTPUT_FORMAT_TEXT: + case DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE: + case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE: + break; + case DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR: + case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR: + /* stderr is meant to machine-readable; skip. */ + return; + } + va_list ap; va_start (ap, cmsgid); @@ -2290,6 +2312,8 @@ diagnostic_output_format_init (diagnostic_context *context, const char *base_file_name, enum diagnostics_output_format format) { + output_format = format; + switch (format) { default: |