diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/analyzer/checker-event.h | 2 | ||||
-rw-r--r-- | gcc/analyzer/checker-path.cc | 8 | ||||
-rw-r--r-- | gcc/analyzer/checker-path.h | 4 | ||||
-rw-r--r-- | gcc/diagnostic-path.h | 10 | ||||
-rw-r--r-- | gcc/diagnostic.cc | 47 | ||||
-rw-r--r-- | gcc/logical-location.h | 5 | ||||
-rw-r--r-- | gcc/simple-diagnostic-path.cc | 11 | ||||
-rw-r--r-- | gcc/simple-diagnostic-path.h | 13 | ||||
-rw-r--r-- | gcc/tree-diagnostic-path.cc | 103 | ||||
-rw-r--r-- | gcc/tree-logical-location.cc | 25 | ||||
-rw-r--r-- | gcc/tree-logical-location.h | 3 |
11 files changed, 161 insertions, 70 deletions
diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h index d0935ac..4343641 100644 --- a/gcc/analyzer/checker-event.h +++ b/gcc/analyzer/checker-event.h @@ -91,7 +91,6 @@ public: /* Implementation of diagnostic_event. */ location_t get_location () const final override { return m_loc; } - tree get_fndecl () const final override { return m_effective_fndecl; } int get_stack_depth () const final override { return m_effective_depth; } const logical_location *get_logical_location () const final override { @@ -111,6 +110,7 @@ public: maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj) const override; /* Additional functionality. */ + tree get_fndecl () const { return m_effective_fndecl; } int get_original_stack_depth () const { return m_original_depth; } diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc index c836191..cfbbc0b 100644 --- a/gcc/analyzer/checker-path.cc +++ b/gcc/analyzer/checker-path.cc @@ -63,6 +63,14 @@ along with GCC; see the file COPYING3. If not see namespace ana { +bool +checker_path::same_function_p (int event_idx_a, + int event_idx_b) const +{ + return (m_events[event_idx_a]->get_fndecl () + == m_events[event_idx_b]->get_fndecl ()); +} + /* Print a single-line representation of this path to PP. */ void diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h index 162ebb3..1aa56d2 100644 --- a/gcc/analyzer/checker-path.h +++ b/gcc/analyzer/checker-path.h @@ -63,6 +63,10 @@ public: return m_events[idx]; } + bool + same_function_p (int event_idx_a, + int event_idx_b) const final override; + void dump (pretty_printer *pp) const; void debug () const; diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h index 958eb72..7497b0a 100644 --- a/gcc/diagnostic-path.h +++ b/gcc/diagnostic-path.h @@ -142,8 +142,6 @@ class diagnostic_event virtual location_t get_location () const = 0; - virtual tree get_fndecl () const = 0; - /* Stack depth, so that consumers can visualize the interprocedural calls, returns, and frame nesting. */ virtual int get_stack_depth () const = 0; @@ -151,7 +149,7 @@ 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. */ + /* Get a logical_location for this event, or nullptr if there is none. */ virtual const logical_location *get_logical_location () const = 0; virtual meaning get_meaning () const = 0; @@ -194,6 +192,12 @@ class diagnostic_path virtual const diagnostic_thread & get_thread (diagnostic_thread_id_t) const = 0; + /* Return true iff the two events are both within the same function, + or both outside of any function. */ + virtual bool + same_function_p (int event_idx_a, + int event_idx_b) const = 0; + bool interprocedural_p () const; bool multithreaded_p () const; diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index a7acde5..844eb8e 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "cpplib.h" #include "text-art/theme.h" #include "pretty-print-urlifier.h" +#include "logical-location.h" #ifdef HAVE_TERMIOS_H # include <termios.h> @@ -1028,9 +1029,9 @@ diagnostic_event::meaning::maybe_get_property_str (enum property p) /* class diagnostic_path. */ -/* Subroutint of diagnostic_path::interprocedural_p. +/* 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 fndecl, and a non-zero stack depth. + 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. */ @@ -1040,12 +1041,13 @@ diagnostic_path::get_first_event_in_a_function (unsigned *out_idx) const const unsigned num = num_events (); for (unsigned i = 0; i < num; i++) { - if (!(get_event (i).get_fndecl () == NULL - && get_event (i).get_stack_depth () == 0)) - { - *out_idx = i; - return true; - } + 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; } @@ -1062,13 +1064,12 @@ diagnostic_path::interprocedural_p () const return false; const diagnostic_event &first_fn_event = get_event (first_fn_event_idx); - tree first_fndecl = first_fn_event.get_fndecl (); 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 (get_event (i).get_fndecl () != first_fndecl) + if (!same_function_p (first_fn_event_idx, i)) return true; if (get_event (i).get_stack_depth () != first_fn_stack_depth) return true; @@ -1076,6 +1077,32 @@ diagnostic_path::interprocedural_p () const return false; } +/* class logical_location. */ + +/* Return true iff this is a function or method. */ + +bool +logical_location::function_p () const +{ + switch (get_kind ()) + { + default: + gcc_unreachable (); + case LOGICAL_LOCATION_KIND_UNKNOWN: + case LOGICAL_LOCATION_KIND_MODULE: + case LOGICAL_LOCATION_KIND_NAMESPACE: + case LOGICAL_LOCATION_KIND_TYPE: + case LOGICAL_LOCATION_KIND_RETURN_TYPE: + case LOGICAL_LOCATION_KIND_PARAMETER: + case LOGICAL_LOCATION_KIND_VARIABLE: + return false; + + case LOGICAL_LOCATION_KIND_FUNCTION: + case LOGICAL_LOCATION_KIND_MEMBER: + return true; + } +} + void default_diagnostic_starter (diagnostic_context *context, const diagnostic_info *diagnostic) diff --git a/gcc/logical-location.h b/gcc/logical-location.h index abe2c3a..c3b7208 100644 --- a/gcc/logical-location.h +++ b/gcc/logical-location.h @@ -67,6 +67,11 @@ public: /* Get what kind of SARIF logicalLocation this is (if any). */ virtual enum logical_location_kind get_kind () const = 0; + + /* Get a string for this location in a form suitable for path output. */ + virtual label_text get_name_for_path_output () const = 0; + + bool function_p () const; }; #endif /* GCC_LOGICAL_LOCATION_H. */ diff --git a/gcc/simple-diagnostic-path.cc b/gcc/simple-diagnostic-path.cc index 3ec0e85..7c47b83 100644 --- a/gcc/simple-diagnostic-path.cc +++ b/gcc/simple-diagnostic-path.cc @@ -72,6 +72,14 @@ simple_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const return *m_threads[idx]; } +bool +simple_diagnostic_path::same_function_p (int event_idx_a, + int event_idx_b) const +{ + return (m_events[event_idx_a]->get_fndecl () + == m_events[event_idx_b]->get_fndecl ()); +} + diagnostic_thread_id_t simple_diagnostic_path::add_thread (const char *name) { @@ -169,7 +177,8 @@ simple_diagnostic_event (location_t loc, int depth, const char *desc, diagnostic_thread_id_t thread_id) -: m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc)), +: m_loc (loc), m_fndecl (fndecl), m_logical_loc (fndecl), + m_depth (depth), m_desc (xstrdup (desc)), m_connected_to_next_event (false), m_thread_id (thread_id) { diff --git a/gcc/simple-diagnostic-path.h b/gcc/simple-diagnostic-path.h index 5fbed15..5147df5 100644 --- a/gcc/simple-diagnostic-path.h +++ b/gcc/simple-diagnostic-path.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_SIMPLE_DIAGNOSTIC_PATH_H #include "diagnostic-path.h" +#include "tree-logical-location.h" /* Concrete subclasses of the abstract base classes declared in diagnostic-path.h. */ @@ -37,7 +38,6 @@ class simple_diagnostic_event : public diagnostic_event ~simple_diagnostic_event (); location_t get_location () const final override { return m_loc; } - tree get_fndecl () const final override { return m_fndecl; } int get_stack_depth () const final override { return m_depth; } label_text get_desc (bool) const final override { @@ -45,7 +45,10 @@ class simple_diagnostic_event : public diagnostic_event } const logical_location *get_logical_location () const final override { - return NULL; + if (m_fndecl) + return &m_logical_loc; + else + return nullptr; } meaning get_meaning () const final override { @@ -65,9 +68,12 @@ class simple_diagnostic_event : public diagnostic_event m_connected_to_next_event = true; } + tree get_fndecl () const { return m_fndecl; } + private: location_t m_loc; tree m_fndecl; + tree_logical_location m_logical_loc; int m_depth; char *m_desc; // has been i18n-ed and formatted bool m_connected_to_next_event; @@ -102,6 +108,9 @@ class simple_diagnostic_path : public diagnostic_path unsigned num_threads () const final override; const diagnostic_thread & get_thread (diagnostic_thread_id_t) const final override; + bool + same_function_p (int event_idx_a, + int event_idx_b) const final override; diagnostic_thread_id_t add_thread (const char *name); diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc index a9dd40c..4287b90 100644 --- a/gcc/tree-diagnostic-path.cc +++ b/gcc/tree-diagnostic-path.cc @@ -43,6 +43,13 @@ along with GCC; see the file COPYING3. If not see #include "selftest-diagnostic.h" #include "text-art/theme.h" +/* Disable warnings about missing quoting in GCC diagnostics for the print + calls below. */ +#if __GNUC__ >= 10 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-diag" +#endif + /* Anonymous namespace for path-printing code. */ namespace { @@ -153,14 +160,17 @@ class path_label : public range_label when printing a diagnostic_path. */ static bool -can_consolidate_events (const diagnostic_event &e1, +can_consolidate_events (const diagnostic_path &path, + const diagnostic_event &e1, + unsigned ev1_idx, const diagnostic_event &e2, + unsigned ev2_idx, bool check_locations) { if (e1.get_thread_id () != e2.get_thread_id ()) return false; - if (e1.get_fndecl () != e2.get_fndecl ()) + if (!path.same_function_p (ev1_idx, ev2_idx)) return false; if (e1.get_stack_depth () != e2.get_stack_depth ()) @@ -196,8 +206,10 @@ class thread_event_printer; class per_thread_summary { public: - per_thread_summary (label_text name, unsigned swimlane_idx) - : m_name (std::move (name)), + per_thread_summary (const diagnostic_path &path, + label_text name, unsigned swimlane_idx) + : m_path (path), + m_name (std::move (name)), m_swimlane_idx (swimlane_idx), m_last_event (nullptr), m_min_depth (INT_MAX), @@ -222,6 +234,8 @@ private: friend class thread_event_printer; friend struct event_range; + const diagnostic_path &m_path; + const label_text m_name; /* The "swimlane index" is the order in which this per_thread_summary @@ -333,7 +347,7 @@ struct event_range bool show_event_links) : m_path (path), m_initial_event (initial_event), - m_fndecl (initial_event.get_fndecl ()), + m_logical_loc (initial_event.get_logical_location ()), m_stack_depth (initial_event.get_stack_depth ()), m_start_idx (start_idx), m_end_idx (start_idx), m_path_label (path, start_idx), @@ -373,10 +387,13 @@ struct event_range return result; } - bool maybe_add_event (const diagnostic_event &new_ev, unsigned idx, + bool maybe_add_event (const diagnostic_event &new_ev, + unsigned new_ev_idx, bool check_rich_locations) { - if (!can_consolidate_events (m_initial_event, new_ev, + if (!can_consolidate_events (*m_path, + m_initial_event, m_start_idx, + new_ev, new_ev_idx, check_rich_locations)) return false; @@ -388,8 +405,8 @@ struct event_range per_source_line_info &source_line_info = get_per_source_line_info (exploc.line); const diagnostic_event *prev_event = nullptr; - if (idx > 0) - prev_event = &m_path->get_event (idx - 1); + if (new_ev_idx > 0) + prev_event = &m_path->get_event (new_ev_idx - 1); const bool has_in_edge = (prev_event ? prev_event->connect_to_next_event_p () : false); @@ -406,7 +423,7 @@ struct event_range false, &m_path_label)) return false; - m_end_idx = idx; + m_end_idx = new_ev_idx; m_per_thread_summary.m_last_event = &new_ev; if (m_show_event_links) @@ -470,7 +487,7 @@ struct event_range const diagnostic_path *m_path; const diagnostic_event &m_initial_event; - tree m_fndecl; + const logical_location *m_logical_loc; int m_stack_depth; unsigned m_start_idx; unsigned m_end_idx; @@ -518,8 +535,10 @@ private: return **slot; const diagnostic_thread &thread = path.get_thread (tid); - per_thread_summary *pts = new per_thread_summary (thread.get_name (false), - m_per_thread_summary.length ()); + per_thread_summary *pts + = new per_thread_summary (path, + thread.get_name (false), + m_per_thread_summary.length ()); m_thread_id_to_events.put (tid, pts); m_per_thread_summary.safe_push (pts); return *pts; @@ -534,12 +553,12 @@ per_thread_summary::interprocedural_p () const { if (m_event_ranges.is_empty ()) return false; - tree first_fndecl = m_event_ranges[0]->m_fndecl; int first_stack_depth = m_event_ranges[0]->m_stack_depth; for (auto range : m_event_ranges) { - if (range->m_fndecl != first_fndecl) - return true; + if (!m_path.same_function_p (m_event_ranges[0]->m_start_idx, + range->m_start_idx)) + return true; if (range->m_stack_depth != first_stack_depth) return true; } @@ -585,23 +604,6 @@ write_indent (pretty_printer *pp, int spaces) pp_space (pp); } -/* Print FNDDECL to PP, quoting it if QUOTED is true. - - We can't use "%qE" here since we can't guarantee the capabilities - of PP. */ - -static void -print_fndecl (pretty_printer *pp, tree fndecl, bool quoted) -{ - const char *n = DECL_NAME (fndecl) - ? identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)) - : _("<anonymous>"); - if (quoted) - pp_printf (pp, "%qs", n); - else - pp_string (pp, n); -} - static const int base_indent = 2; static const int per_frame_indent = 2; @@ -684,10 +686,10 @@ public: m_cur_indent += 5; } } - if (range->m_fndecl) + if (const logical_location *logical_loc = range->m_logical_loc) { - print_fndecl (pp, range->m_fndecl, true); - pp_string (pp, ": "); + label_text name (logical_loc->get_name_for_path_output ()); + pp_printf (pp, "%qs: ", name.get ()); } if (range->m_start_idx == range->m_end_idx) pp_printf (pp, "event %i", @@ -914,15 +916,18 @@ default_tree_diagnostic_path_printer (diagnostic_context *context, if (context->show_path_depths_p ()) { int stack_depth = event.get_stack_depth (); - tree fndecl = event.get_fndecl (); /* -fdiagnostics-path-format=separate-events doesn't print fndecl information, so with -fdiagnostics-show-path-depths print the fndecls too, if any. */ - if (fndecl) - inform (event.get_location (), - "%@ %s (fndecl %qD, depth %i)", - &event_id, event_text.get (), - fndecl, stack_depth); + if (const logical_location *logical_loc + = event.get_logical_location ()) + { + label_text name (logical_loc->get_name_for_path_output ()); + inform (event.get_location (), + "%@ %s (fndecl %qs, depth %i)", + &event_id, event_text.get (), + name.get (), stack_depth); + } else inform (event.get_location (), "%@ %s (depth %i)", @@ -972,11 +977,10 @@ default_tree_make_json_for_path (diagnostic_context *context, event.get_location ())); label_text event_text (event.get_desc (false)); event_obj->set_string ("description", event_text.get ()); - if (tree fndecl = event.get_fndecl ()) + if (const logical_location *logical_loc = event.get_logical_location ()) { - const char *function - = identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)); - event_obj->set_string ("function", function); + label_text name (logical_loc->get_name_for_path_output ()); + event_obj->set_string ("function", name.get ()); } event_obj->set_integer ("depth", event.get_stack_depth ()); path_array->append (event_obj); @@ -986,13 +990,6 @@ default_tree_make_json_for_path (diagnostic_context *context, #if CHECKING_P -/* Disable warnings about missing quoting in GCC diagnostics for the print - calls in the tests below. */ -#if __GNUC__ >= 10 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-diag" -#endif - namespace selftest { /* Return true iff all events in PATH have locations for which column data diff --git a/gcc/tree-logical-location.cc b/gcc/tree-logical-location.cc index 0333b31..ca8b34a 100644 --- a/gcc/tree-logical-location.cc +++ b/gcc/tree-logical-location.cc @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "pretty-print.h" #include "tree-logical-location.h" #include "langhooks.h" +#include "intl.h" /* class compiler_logical_location : public logical_location. */ @@ -82,6 +83,16 @@ compiler_logical_location::get_kind_for_tree (tree decl) } } +label_text +compiler_logical_location::get_name_for_tree_for_path_output (tree decl) +{ + gcc_assert (decl); + const char *n = DECL_NAME (decl) + ? identifier_to_locale (lang_hooks.decl_printable_name (decl, 2)) + : _("<anonymous>"); + return label_text::borrow (n); +} + /* class tree_logical_location : public compiler_logical_location. */ /* Implementation of the logical_location vfuncs, using m_decl. */ @@ -114,6 +125,13 @@ tree_logical_location::get_kind () const return get_kind_for_tree (m_decl); } +label_text +tree_logical_location::get_name_for_path_output () const +{ + gcc_assert (m_decl); + return get_name_for_tree_for_path_output (m_decl); +} + /* class current_fndecl_logical_location : public compiler_logical_location. */ /* Implementation of the logical_location vfuncs, using @@ -146,3 +164,10 @@ current_fndecl_logical_location::get_kind () const gcc_assert (current_function_decl); return get_kind_for_tree (current_function_decl); } + +label_text +current_fndecl_logical_location::get_name_for_path_output () const +{ + gcc_assert (current_function_decl); + return get_name_for_tree_for_path_output (current_function_decl); +} diff --git a/gcc/tree-logical-location.h b/gcc/tree-logical-location.h index feaad6e..8634f3a 100644 --- a/gcc/tree-logical-location.h +++ b/gcc/tree-logical-location.h @@ -33,6 +33,7 @@ class compiler_logical_location : public logical_location static const char *get_name_with_scope_for_tree (tree); static const char *get_internal_name_for_tree (tree); static enum logical_location_kind get_kind_for_tree (tree); + static label_text get_name_for_tree_for_path_output (tree); }; /* Concrete subclass of logical_location, with reference to a specific @@ -47,6 +48,7 @@ public: const char *get_name_with_scope () const final override; const char *get_internal_name () const final override; enum logical_location_kind get_kind () const final override; + label_text get_name_for_path_output () const final override; private: tree m_decl; @@ -62,6 +64,7 @@ public: const char *get_name_with_scope () const final override; const char *get_internal_name () const final override; enum logical_location_kind get_kind () const final override; + label_text get_name_for_path_output () const final override; }; #endif /* GCC_TREE_LOGICAL_LOCATION_H. */ |