mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
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. gcc/ChangeLog: PR middle-end/114348 * diagnostic-format-json.cc (json_stderr_output_format::machine_readable_stderr_p): New. (json_file_output_format::machine_readable_stderr_p): New. * diagnostic-format-sarif.cc (sarif_stream_output_format::machine_readable_stderr_p): New. (sarif_file_output_format::machine_readable_stderr_p): New. * diagnostic.cc (diagnostic_context::action_after_output): Move "fnotice" to before "finish" call, so that we still have the diagnostic_context. (fnotice): Bail out if the user requested one of the machine-readable diagnostic output formats on stderr. * diagnostic.h (diagnostic_output_format::machine_readable_stderr_p): New pure virtual function. (diagnostic_text_output_format::machine_readable_stderr_p): New. (diagnostic_context::get_output_format): New accessor. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
bc91e3870e
commit
0bf99b1b7e
@ -314,6 +314,10 @@ public:
|
||||
{
|
||||
flush_to_file (stderr);
|
||||
}
|
||||
bool machine_readable_stderr_p () const final override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class json_file_output_format : public json_output_format
|
||||
@ -345,6 +349,10 @@ public:
|
||||
fclose (outf);
|
||||
free (filename);
|
||||
}
|
||||
bool machine_readable_stderr_p () const final override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
char *m_base_file_name;
|
||||
|
@ -1750,6 +1750,10 @@ public:
|
||||
{
|
||||
m_builder.flush_to_file (m_stream);
|
||||
}
|
||||
bool machine_readable_stderr_p () const final override
|
||||
{
|
||||
return m_stream == stderr;
|
||||
}
|
||||
private:
|
||||
FILE *m_stream;
|
||||
};
|
||||
@ -1782,6 +1786,10 @@ public:
|
||||
fclose (outf);
|
||||
free (filename);
|
||||
}
|
||||
bool machine_readable_stderr_p () const final override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
char *m_base_file_name;
|
||||
|
@ -802,8 +802,8 @@ diagnostic_context::action_after_output (diagnostic_t diag_kind)
|
||||
case DK_FATAL:
|
||||
if (m_abort_on_error)
|
||||
real_abort ();
|
||||
finish ();
|
||||
fnotice (stderr, "compilation terminated.\n");
|
||||
finish ();
|
||||
exit (FATAL_EXIT_CODE);
|
||||
|
||||
default:
|
||||
@ -2264,6 +2264,16 @@ diagnostic_context::emit_diagram (const diagnostic_diagram &diagram)
|
||||
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)
|
||||
if (const diagnostic_output_format *output_format
|
||||
= global_dc->get_output_format ())
|
||||
if (output_format->machine_readable_stderr_p ())
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, cmsgid);
|
||||
|
@ -210,6 +210,7 @@ public:
|
||||
virtual void on_end_diagnostic (const diagnostic_info &,
|
||||
diagnostic_t orig_diag_kind) = 0;
|
||||
virtual void on_diagram (const diagnostic_diagram &diagram) = 0;
|
||||
virtual bool machine_readable_stderr_p () const = 0;
|
||||
|
||||
protected:
|
||||
diagnostic_output_format (diagnostic_context &context)
|
||||
@ -238,6 +239,10 @@ public:
|
||||
void on_end_diagnostic (const diagnostic_info &,
|
||||
diagnostic_t orig_diag_kind) override;
|
||||
void on_diagram (const diagnostic_diagram &diagram) override;
|
||||
bool machine_readable_stderr_p () const final override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/* A stack of sets of classifications: each entry in the stack is
|
||||
@ -432,6 +437,11 @@ public:
|
||||
|
||||
void emit_diagram (const diagnostic_diagram &diagram);
|
||||
|
||||
const diagnostic_output_format *get_output_format () const
|
||||
{
|
||||
return m_output_format;
|
||||
}
|
||||
|
||||
/* Various setters for use by option-handling logic. */
|
||||
void set_output_format (diagnostic_output_format *output_format);
|
||||
void set_text_art_charset (enum diagnostic_text_art_charset charset);
|
||||
|
Loading…
Reference in New Issue
Block a user