[pushed] analyzer: add sarif properties for checker events

Message ID 20240104142728.427423-1-dmalcolm@redhat.com
State Unresolved
Headers
Series [pushed] analyzer: add sarif properties for checker events |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

David Malcolm Jan. 4, 2024, 2:27 p.m. UTC
  As another followup to r14-6057-g12b67d1e13b3cf, optionally add SARIF
property bags to threadFlowLocation objects when writing out diagnostic
paths, and add analyzer-specific properties to them.

This was useful for debugging PR analyzer/112790.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Successful run of analyzer integration tests on x86_64-pc-linux-gnu.
Pushed to trunk as r14-6919-g05c99b1c7965f4.

gcc/analyzer/ChangeLog:
	* checker-event.cc: Include "diagnostic-format-sarif.h" and
	"tree-logical-location.h".
	(checker_event::maybe_add_sarif_properties): New.
	(superedge_event::maybe_add_sarif_properties): New.
	(superedge_event::superedge_event): Add comment.
	* checker-event.h (checker_event::maybe_add_sarif_properties): New
	decl.
	(superedge_event::maybe_add_sarif_properties): New decl.

gcc/ChangeLog:
	* diagnostic-format-sarif.cc
	(sarif_builder::make_logical_location_object): Convert to...
	(make_sarif_logical_location_object): ...this.
	(sarif_builder::set_any_logical_locs_arr): Update for above
	change.
	(sarif_builder::make_thread_flow_location_object): Call
	maybe_add_sarif_properties on each diagnostic_event.
	* diagnostic-format-sarif.h (class logical_location): New forward
	decl.
	(make_sarif_logical_location_object): New decl.
	* diagnostic-path.h (class sarif_object): New forward decl.
	(diagnostic_event::maybe_add_sarif_properties): New vfunc.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 gcc/analyzer/checker-event.cc  | 43 ++++++++++++++++++++++++++++++++++
 gcc/analyzer/checker-event.h   |  6 +++++
 gcc/diagnostic-format-sarif.cc | 13 +++++-----
 gcc/diagnostic-format-sarif.h  |  5 ++++
 gcc/diagnostic-path.h          |  9 +++++++
 5 files changed, 70 insertions(+), 6 deletions(-)
  

Patch

diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
index 3cb2fb9175cd..8ce35f22e20e 100644
--- a/gcc/analyzer/checker-event.cc
+++ b/gcc/analyzer/checker-event.cc
@@ -55,6 +55,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/constraint-manager.h"
 #include "analyzer/checker-event.h"
 #include "analyzer/exploded-graph.h"
+#include "diagnostic-format-sarif.h"
+#include "tree-logical-location.h"
 
 #if ENABLE_ANALYZER
 
@@ -142,6 +144,30 @@  checker_event::get_meaning () const
   return meaning ();
 }
 
+/* Implementation of diagnostic_event::maybe_add_sarif_properties
+   for checker_event.  */
+
+void
+checker_event::
+maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj) const
+{
+  sarif_property_bag &props = thread_flow_loc_obj.get_or_create_properties ();
+#define PROPERTY_PREFIX "gcc/analyzer/checker_event/"
+  props.set (PROPERTY_PREFIX "emission_id",
+	     diagnostic_event_id_to_json  (m_emission_id));
+  props.set_string (PROPERTY_PREFIX "kind", event_kind_to_string (m_kind));
+
+  if (m_original_fndecl != m_effective_fndecl)
+    {
+      tree_logical_location logical_loc (m_original_fndecl);
+      props.set (PROPERTY_PREFIX "original_fndecl",
+		 make_sarif_logical_location_object (logical_loc));
+    }
+  if (m_original_depth != m_effective_depth)
+    props.set_integer (PROPERTY_PREFIX "original_depth", m_original_depth);
+#undef PROPERTY_PREFIX
+}
+
 /* Dump this event to PP (for debugging/logging purposes).  */
 
 void
@@ -498,6 +524,21 @@  state_change_event::get_meaning () const
 
 /* class superedge_event : public checker_event.  */
 
+/* Implementation of diagnostic_event::maybe_add_sarif_properties
+   for superedge_event.  */
+
+void
+superedge_event::maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj)
+  const
+{
+  checker_event::maybe_add_sarif_properties (thread_flow_loc_obj);
+  sarif_property_bag &props = thread_flow_loc_obj.get_or_create_properties ();
+#define PROPERTY_PREFIX "gcc/analyzer/superedge_event/"
+  if (m_sedge)
+    props.set (PROPERTY_PREFIX "superedge", m_sedge->to_json ());
+#undef PROPERTY_PREFIX
+}
+
 /* Get the callgraph_superedge for this superedge_event, which must be
    for an interprocedural edge, rather than a CFG edge.  */
 
@@ -548,6 +589,8 @@  superedge_event::superedge_event (enum event_kind kind,
   m_eedge (eedge), m_sedge (eedge.m_sedge),
   m_var (NULL_TREE), m_critical_state (0)
 {
+  /* Note that m_sedge can be nullptr for e.g. jumps through
+     function pointers.  */
 }
 
 /* class cfg_edge_event : public superedge_event.  */
diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h
index dcb2e27faa60..72ee103076c8 100644
--- a/gcc/analyzer/checker-event.h
+++ b/gcc/analyzer/checker-event.h
@@ -118,6 +118,9 @@  public:
     return 0;
   }
 
+  void
+  maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj) const override;
+
   /* Additional functionality.  */
 
   int get_original_stack_depth () const { return m_original_depth; }
@@ -391,6 +394,9 @@  public:
 class superedge_event : public checker_event
 {
 public:
+  void maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj)
+    const override;
+
   /* Mark this edge event as being either an interprocedural call or
      return in which VAR is in STATE, and that this is critical to the
      diagnostic (so that get_desc can attempt to get a better description
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index 05b2c6df2e27..7b903bc90c35 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -184,8 +184,6 @@  private:
   void set_any_logical_locs_arr (json::object *location_obj,
 				 const logical_location *logical_loc);
   json::object *make_location_object (const diagnostic_event &event);
-  json::object *
-  make_logical_location_object (const logical_location &logical_loc) const;
   json::object *make_code_flow_object (const diagnostic_path &path);
   json::object *
   make_thread_flow_location_object (const diagnostic_event &event,
@@ -754,7 +752,7 @@  set_any_logical_locs_arr (json::object *location_obj,
 {
   if (!logical_loc)
     return;
-  json::object *logical_loc_obj = make_logical_location_object (*logical_loc);
+  json::object *logical_loc_obj = make_sarif_logical_location_object (*logical_loc);
   json::array *location_locs_arr = new json::array ();
   location_locs_arr->append (logical_loc_obj);
   location_obj->set ("logicalLocations", location_locs_arr);
@@ -1092,8 +1090,7 @@  maybe_get_sarif_kind (enum logical_location_kind kind)
    or return NULL.  */
 
 json::object *
-sarif_builder::
-make_logical_location_object (const logical_location &logical_loc) const
+make_sarif_logical_location_object (const logical_location &logical_loc)
 {
   json::object *logical_loc_obj = new json::object ();
 
@@ -1163,7 +1160,11 @@  json::object *
 sarif_builder::make_thread_flow_location_object (const diagnostic_event &ev,
 						 int path_event_idx)
 {
-  json::object *thread_flow_loc_obj = new json::object ();
+  sarif_object *thread_flow_loc_obj = new sarif_object ();
+
+  /* Give diagnostic_event subclasses a chance to add custom properties
+     via a property bag.  */
+  ev.maybe_add_sarif_properties (*thread_flow_loc_obj);
 
   /* "location" property (SARIF v2.1.0 section 3.38.3).  */
   json::object *location_obj = make_location_object (ev);
diff --git a/gcc/diagnostic-format-sarif.h b/gcc/diagnostic-format-sarif.h
index 82ed9b9ee440..485564e14214 100644
--- a/gcc/diagnostic-format-sarif.h
+++ b/gcc/diagnostic-format-sarif.h
@@ -23,6 +23,8 @@  along with GCC; see the file COPYING3.  If not see
 
 #include "json.h"
 
+class logical_location;
+
 /* Concrete subclass of json::object for SARIF property bags
    (SARIF v2.1.0 section 3.8).  */
 
@@ -42,4 +44,7 @@  public:
   sarif_property_bag &get_or_create_properties ();
 };
 
+extern json::object *
+make_sarif_logical_location_object (const logical_location &logical_loc);
+
 #endif /* ! GCC_DIAGNOSTIC_FORMAT_SARIF_H */
diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h
index d39872abb9f6..d24fb50b8d80 100644
--- a/gcc/diagnostic-path.h
+++ b/gcc/diagnostic-path.h
@@ -24,6 +24,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "diagnostic.h" /* for ATTRIBUTE_GCC_DIAG.  */
 #include "diagnostic-event-id.h"
 
+class sarif_object;
+
 /* A diagnostic_path is an optional additional piece of metadata associated
    with a diagnostic (via its rich_location).
 
@@ -157,6 +159,13 @@  class diagnostic_event
   virtual meaning get_meaning () const = 0;
 
   virtual diagnostic_thread_id_t get_thread_id () const = 0;
+
+  /* Hook for SARIF output to allow for adding diagnostic-specific
+     properties to the threadFlowLocation object's property bag.  */
+  virtual void
+  maybe_add_sarif_properties (sarif_object &/*thread_flow_loc_obj*/) const
+  {
+  }
 };
 
 /* Abstract base class representing a thread of execution within