aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/analyzer/checker-event.h2
-rw-r--r--gcc/analyzer/checker-path.cc8
-rw-r--r--gcc/analyzer/checker-path.h4
-rw-r--r--gcc/diagnostic-path.h10
-rw-r--r--gcc/diagnostic.cc47
-rw-r--r--gcc/logical-location.h5
-rw-r--r--gcc/simple-diagnostic-path.cc11
-rw-r--r--gcc/simple-diagnostic-path.h13
-rw-r--r--gcc/tree-diagnostic-path.cc103
-rw-r--r--gcc/tree-logical-location.cc25
-rw-r--r--gcc/tree-logical-location.h3
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. */