aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostic-path.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-06-21 18:20:38 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-06-21 18:20:38 -0400
commit4819dc7d4b84afa98881ffb8471cf19bc362221b (patch)
tree885a33a86b05a5e6c0a73ccb6bbb9e0f715cb758 /gcc/diagnostic-path.cc
parent37f3000a57d62b808188eb6a14a369f6a789e1ea (diff)
downloadgcc-4819dc7d4b84afa98881ffb8471cf19bc362221b.zip
gcc-4819dc7d4b84afa98881ffb8471cf19bc362221b.tar.gz
gcc-4819dc7d4b84afa98881ffb8471cf19bc362221b.tar.bz2
diagnostics: move diagnostic_{event,path} functions to diagnostic-path.cc
No functional change intended. gcc/ChangeLog: * diagnostic-path.cc (diagnostic_event::meaning::dump_to_pp): Move here from diagnostic.cc. (diagnostic_event::meaning::maybe_get_verb_str): Likewise. (diagnostic_event::meaning::maybe_get_noun_str): Likewise. (diagnostic_event::meaning::maybe_get_property_str): Likewise. (diagnostic_path::get_first_event_in_a_function): Likewise. (diagnostic_path::interprocedural_p): Likewise. (debug): Likewise for diagnostic_path * overload. * diagnostic.cc (diagnostic_event::meaning::dump_to_pp): Move from here to diagnostic-path.cc. (diagnostic_event::meaning::maybe_get_verb_str): Likewise. (diagnostic_event::meaning::maybe_get_noun_str): Likewise. (diagnostic_event::meaning::maybe_get_property_str): Likewise. (diagnostic_path::get_first_event_in_a_function): Likewise. (diagnostic_path::interprocedural_p): Likewise. (debug): Likewise for diagnostic_path * overload. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/diagnostic-path.cc')
-rw-r--r--gcc/diagnostic-path.cc168
1 files changed, 168 insertions, 0 deletions
diff --git a/gcc/diagnostic-path.cc b/gcc/diagnostic-path.cc
index 882dc1c..ea5b1f6 100644
--- a/gcc/diagnostic-path.cc
+++ b/gcc/diagnostic-path.cc
@@ -45,6 +45,174 @@ along with GCC; see the file COPYING3. If not see
# pragma GCC diagnostic ignored "-Wformat-diag"
#endif
+/* class diagnostic_event. */
+
+/* struct diagnostic_event::meaning. */
+
+void
+diagnostic_event::meaning::dump_to_pp (pretty_printer *pp) const
+{
+ bool need_comma = false;
+ pp_character (pp, '{');
+ if (const char *verb_str = maybe_get_verb_str (m_verb))
+ {
+ pp_printf (pp, "verb: %qs", verb_str);
+ need_comma = true;
+ }
+ if (const char *noun_str = maybe_get_noun_str (m_noun))
+ {
+ if (need_comma)
+ pp_string (pp, ", ");
+ pp_printf (pp, "noun: %qs", noun_str);
+ need_comma = true;
+ }
+ if (const char *property_str = maybe_get_property_str (m_property))
+ {
+ if (need_comma)
+ pp_string (pp, ", ");
+ pp_printf (pp, "property: %qs", property_str);
+ need_comma = true;
+ }
+ pp_character (pp, '}');
+}
+
+/* Get a string (or NULL) for V suitable for use within a SARIF
+ threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
+
+const char *
+diagnostic_event::meaning::maybe_get_verb_str (enum verb v)
+{
+ switch (v)
+ {
+ default:
+ gcc_unreachable ();
+ case VERB_unknown:
+ return NULL;
+ case VERB_acquire:
+ return "acquire";
+ case VERB_release:
+ return "release";
+ case VERB_enter:
+ return "enter";
+ case VERB_exit:
+ return "exit";
+ case VERB_call:
+ return "call";
+ case VERB_return:
+ return "return";
+ case VERB_branch:
+ return "branch";
+ case VERB_danger:
+ return "danger";
+ }
+}
+
+/* Get a string (or NULL) for N suitable for use within a SARIF
+ threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
+
+const char *
+diagnostic_event::meaning::maybe_get_noun_str (enum noun n)
+{
+ switch (n)
+ {
+ default:
+ gcc_unreachable ();
+ case NOUN_unknown:
+ return NULL;
+ case NOUN_taint:
+ return "taint";
+ case NOUN_sensitive:
+ return "sensitive";
+ case NOUN_function:
+ return "function";
+ case NOUN_lock:
+ return "lock";
+ case NOUN_memory:
+ return "memory";
+ case NOUN_resource:
+ return "resource";
+ }
+}
+
+/* Get a string (or NULL) for P suitable for use within a SARIF
+ threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
+
+const char *
+diagnostic_event::meaning::maybe_get_property_str (enum property p)
+{
+ switch (p)
+ {
+ default:
+ gcc_unreachable ();
+ case PROPERTY_unknown:
+ return NULL;
+ case PROPERTY_true:
+ return "true";
+ case PROPERTY_false:
+ return "false";
+ }
+}
+
+/* class diagnostic_path. */
+
+/* Subroutine of diagnostic_path::interprocedural_p.
+ Look for the first event in this path that is within a function
+ i.e. has a non-null logical location for which function_p is true.
+ If found, write its index to *OUT_IDX and return true.
+ Otherwise return false. */
+
+bool
+diagnostic_path::get_first_event_in_a_function (unsigned *out_idx) const
+{
+ const unsigned num = num_events ();
+ for (unsigned i = 0; i < num; i++)
+ {
+ const diagnostic_event &event = get_event (i);
+ if (const logical_location *logical_loc = event.get_logical_location ())
+ if (logical_loc->function_p ())
+ {
+ *out_idx = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Return true if the events in this path involve more than one
+ function, or false if it is purely intraprocedural. */
+
+bool
+diagnostic_path::interprocedural_p () const
+{
+ /* Ignore leading events that are outside of any function. */
+ unsigned first_fn_event_idx;
+ if (!get_first_event_in_a_function (&first_fn_event_idx))
+ return false;
+
+ const diagnostic_event &first_fn_event = get_event (first_fn_event_idx);
+ int first_fn_stack_depth = first_fn_event.get_stack_depth ();
+
+ const unsigned num = num_events ();
+ for (unsigned i = first_fn_event_idx + 1; i < num; i++)
+ {
+ if (!same_function_p (first_fn_event_idx, i))
+ return true;
+ if (get_event (i).get_stack_depth () != first_fn_stack_depth)
+ return true;
+ }
+ return false;
+}
+
+/* Print PATH by emitting a dummy "note" associated with it. */
+
+DEBUG_FUNCTION
+void debug (diagnostic_path *path)
+{
+ rich_location richloc (line_table, UNKNOWN_LOCATION);
+ richloc.set_path (path);
+ inform (&richloc, "debug path");
+}
+
/* Anonymous namespace for path-printing code. */
namespace {