summaryrefslogtreecommitdiff
path: root/gcc/diagnostic-path.h
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-06-02 15:40:22 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2022-06-02 15:40:22 -0400
commit6cf276ddf22066af780335cd0072d2c27aabe468 (patch)
treea765d4f8d248aa7a4cebe46e77c3eace8c99ad6f /gcc/diagnostic-path.h
parent5ab73173cca4610e59df8a3fe9cb5b30ded75aec (diff)
downloadgcc-6cf276ddf22066af780335cd0072d2c27aabe468.tar.gz
diagnostics: add SARIF output format
This patch adds support to gcc's diagnostic subsystem for emitting diagnostics in SARIF, aka the Static Analysis Results Interchange Format: https://sarifweb.azurewebsites.net/ by extending -fdiagnostics-format= to add two new options: -fdiagnostics-format=sarif-stderr and: -fdiagnostics-format=sarif-file The patch targets SARIF v2.1.0 This is a JSON-based format suited for capturing the results of static analysis tools (like GCC's -fanalyzer), but it can also be used for plain GCC warnings and errors. SARIF supports per-event metadata in diagnostic paths such as ["acquire", "resource"] and ["release", "lock"] (specifically, the threadFlowLocation "kinds" property: SARIF v2.1.0 section 3.38.8), so the patch extends GCC"s diagnostic_event subclass with a "struct meaning" with similar purpose. The patch implements this for -fanalyzer so that the various state-machine-based warnings set these in the SARIF output. The heart of the implementation is in the new file diagnostic-format-sarif.cc. Much of the rest of the patch is interface classes, isolating the diagnostic subsystem (which has no knowledge of e.g. tree or langhook) from the "client" code in the compiler proper cc1 etc). The patch adds a langhook for specifying the SARIF v2.1.0 "artifact.sourceLanguage" property, based on the list in SARIF v2.1.0 Appendix J. The patch adds automated DejaGnu tests to our testsuite via new scan-sarif-file and scan-sarif-file-not directives (although these merely use regexps, rather than attempting to use a proper JSON parser). I've tested the patch by hand using the validator at: https://sarifweb.azurewebsites.net/Validation and the react-based viewer at: https://microsoft.github.io/sarif-web-component/ which successfully shows most of the information (although not paths, and not CWE IDs), and I've fixed all validation errors I've seen (though bugs no doubt remain). I've also tested the generated SARIF using the VS Code extension linked to from the SARIF website; I'm a novice with VS Code, but it seems to be able to handle my generated SARIF files (e.g. showing the data in the SARIF tab, and showing squiggly underlines under issues, and when I click on them, it visualizes the events in the path inline within the source window). Has anyone written an Emacs mode for SARIF files? (pretty please) gcc/ChangeLog: * Makefile.in (OBJS): Add tree-diagnostic-client-data-hooks.o and tree-logical-location.o. (OBJS-libcommon): Add diagnostic-format-sarif.o; reorder. (CFLAGS-tree-diagnostic-client-data-hooks.o): Add TARGET_NAME. * common.opt (fdiagnostics-format=): Add sarif-stderr and sarif-file. (sarif-stderr, sarif-file): New enum values. * diagnostic-client-data-hooks.h: New file. * diagnostic-format-sarif.cc: New file. * diagnostic-path.h (enum diagnostic_event::verb): New enum. (enum diagnostic_event::noun): New enum. (enum diagnostic_event::property): New enum. (struct diagnostic_event::meaning): New struct. (diagnostic_event::get_logical_location): New vfunc. (diagnostic_event::get_meaning): New vfunc. (simple_diagnostic_event::get_logical_location): New vfunc impl. (simple_diagnostic_event::get_meaning): New vfunc impl. * diagnostic.cc: Include "diagnostic-client-data-hooks.h". (diagnostic_initialize): Initialize m_client_data_hooks. (diagnostic_finish): Clean up m_client_data_hooks. (diagnostic_event::meaning::dump_to_pp): New. (diagnostic_event::meaning::maybe_get_verb_str): New. (diagnostic_event::meaning::maybe_get_noun_str): New. (diagnostic_event::meaning::maybe_get_property_str): New. (get_cwe_url): Make non-static. (diagnostic_output_format_init): Handle DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR and DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE. * diagnostic.h (enum diagnostics_output_format): Add DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR and DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE. (class diagnostic_client_data_hooks): New forward decl. (class logical_location): New forward decl. (diagnostic_context::m_client_data_hooks): New field. (diagnostic_output_format_init_sarif_stderr): New decl. (diagnostic_output_format_init_sarif_file): New decl. (get_cwe_url): New decl. * doc/invoke.texi (-fdiagnostics-format=): Add sarif-stderr and sarif-file. * doc/sourcebuild.texi (Scan a particular file): Add scan-sarif-file and scan-sarif-file-not. * langhooks-def.h (lhd_get_sarif_source_language): New decl. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): New macro. (LANG_HOOKS_INITIALIZER): Add LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE. * langhooks.cc (lhd_get_sarif_source_language): New. * langhooks.h (lang_hooks::get_sarif_source_language): New field. * logical-location.h: New file. * plugin.cc (struct for_each_plugin_closure): New. (for_each_plugin_cb): New. (for_each_plugin): New. * plugin.h (for_each_plugin): New decl. * tree-diagnostic-client-data-hooks.cc: New file. * tree-diagnostic.cc: Include "diagnostic-client-data-hooks.h". (tree_diagnostics_defaults): Populate m_client_data_hooks. * tree-logical-location.cc: New file. * tree-logical-location.h: New file. gcc/ada/ChangeLog: * gcc-interface/misc.cc (gnat_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/analyzer/ChangeLog: * checker-path.cc (checker_event::get_meaning): New. (function_entry_event::get_meaning): New. (state_change_event::get_desc): Add dump of meaning of the event to the -fanalyzer-verbose-state-changes output. (state_change_event::get_meaning): New. (cfg_edge_event::get_meaning): New. (call_event::get_meaning): New. (return_event::get_meaning): New. (start_consolidated_cfg_edges_event::get_meaning): New. (warning_event::get_meaning): New. * checker-path.h: Include "tree-logical-location.h". (checker_event::checker_event): Construct m_logical_loc. (checker_event::get_logical_location): New. (checker_event::get_meaning): New decl. (checker_event::m_logical_loc): New. (function_entry_event::get_meaning): New decl. (state_change_event::get_meaning): New decl. (cfg_edge_event::get_meaning): New decl. (call_event::get_meaning): New decl. (return_event::get_meaning): New decl. (start_consolidated_cfg_edges_event::get_meaning): New. (warning_event::get_meaning): New decl. * pending-diagnostic.h: Include "diagnostic-path.h". (pending_diagnostic::get_meaning_for_state_change): New vfunc. * sm-file.cc (file_diagnostic::get_meaning_for_state_change): New vfunc impl. * sm-malloc.cc (malloc_diagnostic::get_meaning_for_state_change): Likewise. * sm-sensitive.cc (exposure_through_output_file::get_meaning_for_state_change): Likewise. * sm-taint.cc (taint_diagnostic::get_meaning_for_state_change): Likewise. * varargs.cc (va_list_sm_diagnostic::get_meaning_for_state_change): Likewise. gcc/c/ChangeLog: * c-lang.cc (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. (c_get_sarif_source_language): New. * c-tree.h (c_get_sarif_source_language): New decl. gcc/cp/ChangeLog: * cp-lang.cc (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. (cp_get_sarif_source_language): New. gcc/d/ChangeLog: * d-lang.cc (d_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/fortran/ChangeLog: * f95-lang.cc (gfc_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/go/ChangeLog: * go-lang.cc (go_get_sarif_source_language): New. (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. gcc/objc/ChangeLog: * objc-act.h (objc_get_sarif_source_language): New decl. * objc-lang.cc (LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE): Redefine. (objc_get_sarif_source_language): New. gcc/testsuite/ChangeLog: * c-c++-common/diagnostic-format-sarif-file-1.c: New test. * c-c++-common/diagnostic-format-sarif-file-2.c: New test. * c-c++-common/diagnostic-format-sarif-file-3.c: New test. * c-c++-common/diagnostic-format-sarif-file-4.c: New test. * gcc.dg/analyzer/file-meaning-1.c: New test. * gcc.dg/analyzer/malloc-meaning-1.c: New test. * gcc.dg/analyzer/malloc-sarif-1.c: New test. * gcc.dg/plugin/analyzer_gil_plugin.c (gil_diagnostic::get_meaning_for_state_change): New vfunc impl. * gcc.dg/plugin/diagnostic-test-paths-5.c: New test. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add diagnostic-test-paths-5.c to tests for diagnostic_plugin_test_paths.c. * lib/gcc-dg.exp: Load scansarif.exp. * lib/scansarif.exp: New test. libatomic/ChangeLog: * testsuite/lib/libatomic.exp: Add load_gcc_lib of scansarif.exp. libgomp/ChangeLog: * testsuite/lib/libgomp.exp: Add load_gcc_lib of scansarif.exp. libitm/ChangeLog: * testsuite/lib/libitm.exp: Add load_gcc_lib of scansarif.exp. libphobos/ChangeLog: * testsuite/lib/libphobos-dg.exp: Add load_gcc_lib of scansarif.exp. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/diagnostic-path.h')
-rw-r--r--gcc/diagnostic-path.h82
1 files changed, 82 insertions, 0 deletions
diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h
index 6c1190d6f2d..8ce4ff763d4 100644
--- a/gcc/diagnostic-path.h
+++ b/gcc/diagnostic-path.h
@@ -69,6 +69,75 @@ along with GCC; see the file COPYING3. If not see
class diagnostic_event
{
public:
+ /* Enums for giving a sense of what this event means.
+ Roughly corresponds to SARIF v2.1.0 section 3.38.8. */
+ enum verb
+ {
+ VERB_unknown,
+
+ VERB_acquire,
+ VERB_release,
+ VERB_enter,
+ VERB_exit,
+ VERB_call,
+ VERB_return,
+ VERB_branch,
+
+ VERB_danger
+ };
+ enum noun
+ {
+ NOUN_unknown,
+
+ NOUN_taint,
+ NOUN_sensitive, // this one isn't in SARIF v2.1.0; filed as https://github.com/oasis-tcs/sarif-spec/issues/530
+ NOUN_function,
+ NOUN_lock,
+ NOUN_memory,
+ NOUN_resource
+ };
+ enum property
+ {
+ PROPERTY_unknown,
+
+ PROPERTY_true,
+ PROPERTY_false
+ };
+ /* A bundle of such enums, allowing for descriptions of the meaning of
+ an event, such as
+ - "acquire memory": meaning (VERB_acquire, NOUN_memory)
+ - "take true branch"": meaning (VERB_branch, PROPERTY_true)
+ - "return from function": meaning (VERB_return, NOUN_function)
+ etc, as per SARIF's threadFlowLocation "kinds" property
+ (SARIF v2.1.0 section 3.38.8). */
+ struct meaning
+ {
+ meaning ()
+ : m_verb (VERB_unknown),
+ m_noun (NOUN_unknown),
+ m_property (PROPERTY_unknown)
+ {
+ }
+ meaning (enum verb verb, enum noun noun)
+ : m_verb (verb), m_noun (noun), m_property (PROPERTY_unknown)
+ {
+ }
+ meaning (enum verb verb, enum property property)
+ : m_verb (verb), m_noun (NOUN_unknown), m_property (property)
+ {
+ }
+
+ void dump_to_pp (pretty_printer *pp) const;
+
+ static const char *maybe_get_verb_str (enum verb);
+ static const char *maybe_get_noun_str (enum noun);
+ static const char *maybe_get_property_str (enum property);
+
+ enum verb m_verb;
+ enum noun m_noun;
+ enum property m_property;
+ };
+
virtual ~diagnostic_event () {}
virtual location_t get_location () const = 0;
@@ -81,6 +150,11 @@ class diagnostic_event
/* Get a localized (and possibly colorized) description of this event. */
virtual label_text get_desc (bool can_colorize) const = 0;
+
+ /* Get a logical_location for this event, or NULL. */
+ virtual const logical_location *get_logical_location () const = 0;
+
+ virtual meaning get_meaning () const = 0;
};
/* Abstract base class for getting at a sequence of events. */
@@ -113,6 +187,14 @@ class simple_diagnostic_event : public diagnostic_event
{
return label_text::borrow (m_desc);
}
+ const logical_location *get_logical_location () const final override
+ {
+ return NULL;
+ }
+ meaning get_meaning () const final override
+ {
+ return meaning ();
+ }
private:
location_t m_loc;