https://gcc.gnu.org/g:b7a2697733d19a093cbdd0e200ffce069a4bc812

commit r13-8761-gb7a2697733d19a093cbdd0e200ffce069a4bc812
Author: David Malcolm <dmalc...@redhat.com>
Date:   Thu May 9 13:09:33 2024 -0400

    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 <dmalc...@redhat.com>

Diff:
---
 gcc/diagnostic.cc | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 0f093081161a..a3d84cf0bfae 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:

Reply via email to