From b5910aa9b9d4d13fc9c51709c3521d3844890fd5 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 16 Sep 2025 14:54:39 -0400 Subject: [PATCH 65/98] diagnostics: add GCC_SARIF_LOG_{DIRECTORY,PREFIX} [PR117815] This patch adds a check for a new environment variable GCC_SARIF_LOG_DIRECTORY. If set, then GCC will add an extra diagnostic output sink, writing to a file in GCC_SARIF_LOG_DIRECTORY. gcc/ChangeLog: PR other/117815 * diagnostics/sarif-sink.cc (add_sarif_sink_in_directory): New. * diagnostics/sarif-sink.h (add_sarif_sink_in_directory): New decl. * doc/invoke.texi: Document GCC_SARIF_LOG_DIRECTORY and GCC_SARIF_LOG_PREFIX. * toplev.cc: Include "diagnostics/sarif-sink.h". (toplev::main): Check for GCC_SARIF_LOG_DIRECTORY and GCC_SARIF_LOG_PREFIX in the environment, and call diagnostics::add_sarif_sink_in_directory if the former is set. --- gcc/diagnostics/sarif-sink.cc | 44 +++++++++++++++++++++++++++++++++++ gcc/diagnostics/sarif-sink.h | 5 ++++ gcc/doc/invoke.texi | 24 +++++++++++++++++++ gcc/toplev.cc | 11 +++++++++ 4 files changed, 84 insertions(+) diff --git a/gcc/diagnostics/sarif-sink.cc b/gcc/diagnostics/sarif-sink.cc index 4505af3d732a..3f032a0a70e1 100644 --- a/gcc/diagnostics/sarif-sink.cc +++ b/gcc/diagnostics/sarif-sink.cc @@ -4788,6 +4788,50 @@ maybe_open_sarif_sink_for_socket (context &dc) dc.add_sink (std::move (sink_)); } +/* Add another diagnostic sink to DC: write a SARIF file to DIR. + Attempt to generate a unique filename for that file of the form + "PREFIX-XXXXXX". */ + +void +add_sarif_sink_in_directory (context &dc, + const char *dir, + const char *prefix) +{ + gcc_assert (line_table); + gcc_assert (dir); + gcc_assert (prefix); + + if (access (dir, R_OK | W_OK | X_OK) < 0) + fatal_error (UNKNOWN_LOCATION, + "unable to access %qs: %m", dir); + + /* Ideally this would have a ".sarif" suffix, but mkstemp + requires the final 6 characters to be 'X'. */ + label_text filename = label_text::take (xasprintf ("%s/%s-XXXXXX", + dir, prefix)); + int fd = mkstemp (const_cast (filename.get ())); + if (fd < 0) + fatal_error (UNKNOWN_LOCATION, + "unable to open %qs: %m", filename.get ()); + FILE *outf = fdopen (fd, "wb"); + if (!outf) + fatal_error (UNKNOWN_LOCATION, "fdopen failed: %m"); + output_file outfile (outf, true, std::move (filename)); + + /* FIXME: should there be a way to specify other key/value + pairs here? (as per -fdiagnostics-add-output, but as an + environment variable, perhaps). */ + sarif_generation_options sarif_gen_opts; + sarif_gen_opts.m_version = sarif_version::v2_1_0; + + dc.add_sink + (make_sarif_sink + (dc, *line_table, + std::make_unique (true), + sarif_gen_opts, + std::move (outfile))); +} + #if CHECKING_P namespace selftest { diff --git a/gcc/diagnostics/sarif-sink.h b/gcc/diagnostics/sarif-sink.h index 634019fe9f3a..b77ed4b60582 100644 --- a/gcc/diagnostics/sarif-sink.h +++ b/gcc/diagnostics/sarif-sink.h @@ -207,6 +207,11 @@ enum class sarif_rpc_granularity extern void maybe_open_sarif_sink_for_socket (context &ctxt); +extern void +add_sarif_sink_in_directory (context &dc, + const char *dir, + const char *prefix); + } // namespace diagnostics #endif /* ! GCC_DIAGNOSTICS_SARIF_SINK_H */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e633a7daf6d5..9d9c17ca047b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6490,6 +6490,9 @@ also show a SARIF representation of the state. @end table +See also @env{GCC_SARIF_LOG_DIRECTORY} for a way of adding a SARIF +output sink via an environment variable. + @end table As well as scheme-specific keys, the following GCC-related keys are usable @@ -37655,6 +37658,27 @@ set and it cannot connect to it. This feature is experimental and subject to change or removal without notice. + +@vindex GCC_SARIF_LOG_DIRECTORY +@item GCC_SARIF_LOG_DIRECTORY +If @env{GCC_SARIF_LOG_DIRECTORY} is set in the environment, then the +compiler will attempt to write a SARIF 2.1.0 log to a file within that +directory, capturing metadata about the compiler invocation, and any +diagnostics emitted within it. + +This SARIF output is in addition to the standard textual output on stderr, +any diagnostic output sinks added with @option{-fdiagnostics-add-output=}, +or that set by @option{-fdiagnostics-set-output=}. + +By default the file is written to a tempfile of the form +@file{gcc-@var{XXXXXX}}. The prefix @code{gcc} can be changed by +setting @env{GCC_SARIF_LOG_PREFIX}. + +@vindex GCC_SARIF_LOG_PREFIX +@item GCC_SARIF_LOG_PREFIX +@env{GCC_SARIF_LOG_PREFIX} controls the prefix used for filenames +when setting @env{GCC_SARIF_LOG_DIRECTORY}. + @end table @noindent diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 682459220a20..793baa343912 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -2354,8 +2354,19 @@ toplev::main (int argc, char **argv) handle_common_deferred_options (); + diagnostics::maybe_open_sarif_sink_for_socket (*global_dc); + if (const char *sarif_log_dir = getenv ("GCC_SARIF_LOG_DIRECTORY")) + { + const char *sarif_log_prefix = getenv ("GCC_SARIF_LOG_PREFIX"); + if (!sarif_log_prefix) + sarif_log_prefix = "gcc"; + diagnostics::add_sarif_sink_in_directory (*global_dc, + sarif_log_dir, + sarif_log_prefix); + } + init_local_tick (); initialize_plugins (); -- 2.49.0