aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-05-09 13:09:33 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-05-09 13:09:33 -0400
commitb7a2697733d19a093cbdd0e200ffce069a4bc812 (patch)
treebd11de3beea4900ad0100cd293523b7ab1dffea5
parent2a6f99aef7c8522471967b171180d9ba4136da90 (diff)
downloadgcc-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.cc24
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: