analyzer: add sarif properties for checker events

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.

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>
This commit is contained in:
David Malcolm 2024-01-04 09:19:06 -05:00
parent 5743e1899d
commit 05c99b1c79
5 changed files with 70 additions and 6 deletions

View file

@ -55,6 +55,8 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/constraint-manager.h" #include "analyzer/constraint-manager.h"
#include "analyzer/checker-event.h" #include "analyzer/checker-event.h"
#include "analyzer/exploded-graph.h" #include "analyzer/exploded-graph.h"
#include "diagnostic-format-sarif.h"
#include "tree-logical-location.h"
#if ENABLE_ANALYZER #if ENABLE_ANALYZER
@ -142,6 +144,30 @@ checker_event::get_meaning () const
return meaning (); 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). */ /* Dump this event to PP (for debugging/logging purposes). */
void void
@ -498,6 +524,21 @@ state_change_event::get_meaning () const
/* class superedge_event : public checker_event. */ /* 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 /* Get the callgraph_superedge for this superedge_event, which must be
for an interprocedural edge, rather than a CFG edge. */ 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_eedge (eedge), m_sedge (eedge.m_sedge),
m_var (NULL_TREE), m_critical_state (0) 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. */ /* class cfg_edge_event : public superedge_event. */

View file

@ -118,6 +118,9 @@ public:
return 0; return 0;
} }
void
maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj) const override;
/* Additional functionality. */ /* Additional functionality. */
int get_original_stack_depth () const { return m_original_depth; } int get_original_stack_depth () const { return m_original_depth; }
@ -391,6 +394,9 @@ public:
class superedge_event : public checker_event class superedge_event : public checker_event
{ {
public: 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 /* 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 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 diagnostic (so that get_desc can attempt to get a better description

View file

@ -184,8 +184,6 @@ private:
void set_any_logical_locs_arr (json::object *location_obj, void set_any_logical_locs_arr (json::object *location_obj,
const logical_location *logical_loc); const logical_location *logical_loc);
json::object *make_location_object (const diagnostic_event &event); 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_code_flow_object (const diagnostic_path &path);
json::object * json::object *
make_thread_flow_location_object (const diagnostic_event &event, 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) if (!logical_loc)
return; 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 (); json::array *location_locs_arr = new json::array ();
location_locs_arr->append (logical_loc_obj); location_locs_arr->append (logical_loc_obj);
location_obj->set ("logicalLocations", location_locs_arr); location_obj->set ("logicalLocations", location_locs_arr);
@ -1092,8 +1090,7 @@ maybe_get_sarif_kind (enum logical_location_kind kind)
or return NULL. */ or return NULL. */
json::object * json::object *
sarif_builder:: make_sarif_logical_location_object (const logical_location &logical_loc)
make_logical_location_object (const logical_location &logical_loc) const
{ {
json::object *logical_loc_obj = new json::object (); 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, sarif_builder::make_thread_flow_location_object (const diagnostic_event &ev,
int path_event_idx) 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). */ /* "location" property (SARIF v2.1.0 section 3.38.3). */
json::object *location_obj = make_location_object (ev); json::object *location_obj = make_location_object (ev);

View file

@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see
#include "json.h" #include "json.h"
class logical_location;
/* Concrete subclass of json::object for SARIF property bags /* Concrete subclass of json::object for SARIF property bags
(SARIF v2.1.0 section 3.8). */ (SARIF v2.1.0 section 3.8). */
@ -42,4 +44,7 @@ public:
sarif_property_bag &get_or_create_properties (); 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 */ #endif /* ! GCC_DIAGNOSTIC_FORMAT_SARIF_H */

View file

@ -24,6 +24,8 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h" /* for ATTRIBUTE_GCC_DIAG. */ #include "diagnostic.h" /* for ATTRIBUTE_GCC_DIAG. */
#include "diagnostic-event-id.h" #include "diagnostic-event-id.h"
class sarif_object;
/* A diagnostic_path is an optional additional piece of metadata associated /* A diagnostic_path is an optional additional piece of metadata associated
with a diagnostic (via its rich_location). with a diagnostic (via its rich_location).
@ -157,6 +159,13 @@ class diagnostic_event
virtual meaning get_meaning () const = 0; virtual meaning get_meaning () const = 0;
virtual diagnostic_thread_id_t get_thread_id () 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 /* Abstract base class representing a thread of execution within