* [PATCH 1/7] diagnostics: move simple_diagnostic_{path,thread,event} to their own .h/cc
2024-06-18 15:08 [pushed 0/7] diagnostics: remove "tree" dependency from diagnostic paths David Malcolm
@ 2024-06-18 15:08 ` David Malcolm
2024-06-18 15:08 ` [PATCH 2/7] diagnostics: eliminate "tree" from diagnostic_{event,path} David Malcolm
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: David Malcolm @ 2024-06-18 15:08 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
As work towards eliminating the dependency on "tree" from
path-printing, move these classes to a new simple-diagnostic-path.h/cc.
No functional change intended.
gcc/analyzer/ChangeLog:
* checker-path.h: Include "simple-diagnostic-path.h".
gcc/ChangeLog:
* Makefile.in (OBJS): Add simple-diagnostic-path.o.
* diagnostic-path.h (class simple_diagnostic_event): Move to
simple-diagnostic-path.h.
(class simple_diagnostic_thread): Likewise.
(class simple_diagnostic_path): Likewise.
* diagnostic.cc (simple_diagnostic_path::simple_diagnostic_path):
Move to simple-diagnostic-path.cc.
(simple_diagnostic_path::num_events): Likewise.
(simple_diagnostic_path::get_event): Likewise.
(simple_diagnostic_path::num_threads): Likewise.
(simple_diagnostic_path::get_thread): Likewise.
(simple_diagnostic_path::add_thread): Likewise.
(simple_diagnostic_path::add_event): Likewise.
(simple_diagnostic_path::add_thread_event): Likewise.
(simple_diagnostic_path::connect_to_next_event): Likewise.
(simple_diagnostic_event::simple_diagnostic_event): Likewise.
(simple_diagnostic_event::~simple_diagnostic_event): Likewise.
* selftest-run-tests.cc (selftest::run_tests): Call
selftest::simple_diagnostic_path_cc_tests.
* selftest.h (selftest::simple_diagnostic_path_cc_tests): New
decl.
* simple-diagnostic-path.cc: New file, from the above material.
* simple-diagnostic-path.h: New file, from the above material
from diagnostic-path.h.
* tree-diagnostic-path.cc: Include "simple-diagnostic-path.h".
gcc/testsuite/ChangeLog
* gcc.dg/plugin/diagnostic_plugin_test_paths.c: Include
"simple-diagnostic-path.h".
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/Makefile.in | 1 +
gcc/analyzer/checker-path.h | 1 +
gcc/diagnostic-path.h | 104 +-------
gcc/diagnostic.cc | 149 ------------
gcc/selftest-run-tests.cc | 1 +
gcc/selftest.h | 1 +
gcc/simple-diagnostic-path.cc | 228 ++++++++++++++++++
gcc/simple-diagnostic-path.h | 130 ++++++++++
.../plugin/diagnostic_plugin_test_paths.c | 1 +
gcc/tree-diagnostic-path.cc | 1 +
10 files changed, 366 insertions(+), 251 deletions(-)
create mode 100644 gcc/simple-diagnostic-path.cc
create mode 100644 gcc/simple-diagnostic-path.h
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f5adb647d3f..35f259da858 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1700,6 +1700,7 @@ OBJS = \
ubsan.o \
sanopt.o \
sancov.o \
+ simple-diagnostic-path.o \
tree-call-cdce.o \
tree-cfg.o \
tree-cfgcleanup.o \
diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h
index 6b3e8a34fe5..162ebb3f0d8 100644
--- a/gcc/analyzer/checker-path.h
+++ b/gcc/analyzer/checker-path.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_ANALYZER_CHECKER_PATH_H
#include "analyzer/checker-event.h"
+#include "simple-diagnostic-path.h"
namespace ana {
diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h
index 938bd583a3d..958eb725322 100644
--- a/gcc/diagnostic-path.h
+++ b/gcc/diagnostic-path.h
@@ -201,108 +201,8 @@ private:
bool get_first_event_in_a_function (unsigned *out_idx) const;
};
-/* Concrete subclasses. */
-
-/* A simple implementation of diagnostic_event. */
-
-class simple_diagnostic_event : public diagnostic_event
-{
- public:
- simple_diagnostic_event (location_t loc, tree fndecl, int depth,
- const char *desc,
- diagnostic_thread_id_t thread_id = 0);
- ~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
- {
- return label_text::borrow (m_desc);
- }
- const logical_location *get_logical_location () const final override
- {
- return NULL;
- }
- meaning get_meaning () const final override
- {
- return meaning ();
- }
- bool connect_to_next_event_p () const final override
- {
- return m_connected_to_next_event;
- }
- diagnostic_thread_id_t get_thread_id () const final override
- {
- return m_thread_id;
- }
-
- void connect_to_next_event ()
- {
- m_connected_to_next_event = true;
- }
-
- private:
- location_t m_loc;
- tree m_fndecl;
- int m_depth;
- char *m_desc; // has been i18n-ed and formatted
- bool m_connected_to_next_event;
- diagnostic_thread_id_t m_thread_id;
-};
-
-/* A simple implementation of diagnostic_thread. */
-
-class simple_diagnostic_thread : public diagnostic_thread
-{
-public:
- simple_diagnostic_thread (const char *name) : m_name (name) {}
- label_text get_name (bool) const final override
- {
- return label_text::borrow (m_name);
- }
-
-private:
- const char *m_name; // has been i18n-ed and formatted
-};
-
-/* A simple implementation of diagnostic_path, as a vector of
- simple_diagnostic_event instances. */
-
-class simple_diagnostic_path : public diagnostic_path
-{
- public:
- simple_diagnostic_path (pretty_printer *event_pp);
-
- unsigned num_events () const final override;
- const diagnostic_event & get_event (int idx) const final override;
- unsigned num_threads () const final override;
- const diagnostic_thread &
- get_thread (diagnostic_thread_id_t) const final override;
-
- diagnostic_thread_id_t add_thread (const char *name);
-
- diagnostic_event_id_t add_event (location_t loc, tree fndecl, int depth,
- const char *fmt, ...)
- ATTRIBUTE_GCC_DIAG(5,6);
- diagnostic_event_id_t
- add_thread_event (diagnostic_thread_id_t thread_id,
- location_t loc, tree fndecl, int depth,
- const char *fmt, ...)
- ATTRIBUTE_GCC_DIAG(6,7);
-
- void connect_to_next_event ();
-
- void disable_event_localization () { m_localize_events = false; }
-
- private:
- auto_delete_vec<simple_diagnostic_thread> m_threads;
- auto_delete_vec<simple_diagnostic_event> m_events;
-
- /* (for use by add_event). */
- pretty_printer *m_event_pp;
- bool m_localize_events;
-};
+/* Concrete subclasses of the above can be found in
+ simple-diagnostic-path.h. */
extern void debug (diagnostic_path *path);
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 9d0cb8ea051..a7acde50ab8 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -2517,155 +2517,6 @@ set_text_art_charset (enum diagnostic_text_art_charset charset)
}
}
-/* class simple_diagnostic_path : public diagnostic_path. */
-
-simple_diagnostic_path::simple_diagnostic_path (pretty_printer *event_pp)
-: m_event_pp (event_pp),
- m_localize_events (true)
-{
- add_thread ("main");
-}
-
-/* Implementation of diagnostic_path::num_events vfunc for
- simple_diagnostic_path: simply get the number of events in the vec. */
-
-unsigned
-simple_diagnostic_path::num_events () const
-{
- return m_events.length ();
-}
-
-/* Implementation of diagnostic_path::get_event vfunc for
- simple_diagnostic_path: simply return the event in the vec. */
-
-const diagnostic_event &
-simple_diagnostic_path::get_event (int idx) const
-{
- return *m_events[idx];
-}
-
-unsigned
-simple_diagnostic_path::num_threads () const
-{
- return m_threads.length ();
-}
-
-const diagnostic_thread &
-simple_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const
-{
- return *m_threads[idx];
-}
-
-diagnostic_thread_id_t
-simple_diagnostic_path::add_thread (const char *name)
-{
- m_threads.safe_push (new simple_diagnostic_thread (name));
- return m_threads.length () - 1;
-}
-
-/* Add an event to this path at LOC within function FNDECL at
- stack depth DEPTH.
-
- Use m_context's printer to format FMT, as the text of the new
- event. Localize FMT iff m_localize_events is set.
-
- Return the id of the new event. */
-
-diagnostic_event_id_t
-simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
- const char *fmt, ...)
-{
- pretty_printer *pp = m_event_pp;
- pp_clear_output_area (pp);
-
- rich_location rich_loc (line_table, UNKNOWN_LOCATION);
-
- va_list ap;
-
- va_start (ap, fmt);
-
- text_info ti (m_localize_events ? _(fmt) : fmt,
- &ap, 0, nullptr, &rich_loc);
- pp_format (pp, &ti);
- pp_output_formatted_text (pp);
-
- va_end (ap);
-
- simple_diagnostic_event *new_event
- = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
- m_events.safe_push (new_event);
-
- pp_clear_output_area (pp);
-
- return diagnostic_event_id_t (m_events.length () - 1);
-}
-
-diagnostic_event_id_t
-simple_diagnostic_path::add_thread_event (diagnostic_thread_id_t thread_id,
- location_t loc,
- tree fndecl,
- int depth,
- const char *fmt, ...)
-{
- pretty_printer *pp = m_event_pp;
- pp_clear_output_area (pp);
-
- rich_location rich_loc (line_table, UNKNOWN_LOCATION);
-
- va_list ap;
-
- va_start (ap, fmt);
-
- text_info ti (_(fmt), &ap, 0, nullptr, &rich_loc);
-
- pp_format (pp, &ti);
- pp_output_formatted_text (pp);
-
- va_end (ap);
-
- simple_diagnostic_event *new_event
- = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp),
- thread_id);
- m_events.safe_push (new_event);
-
- pp_clear_output_area (pp);
-
- return diagnostic_event_id_t (m_events.length () - 1);
-}
-
-/* Mark the most recent event on this path (which must exist) as being
- connected to the next one to be added. */
-
-void
-simple_diagnostic_path::connect_to_next_event ()
-{
- gcc_assert (m_events.length () > 0);
- m_events[m_events.length () - 1]->connect_to_next_event ();
-}
-
-/* struct simple_diagnostic_event. */
-
-/* simple_diagnostic_event's ctor. */
-
-simple_diagnostic_event::
-simple_diagnostic_event (location_t loc,
- tree fndecl,
- 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_connected_to_next_event (false),
- m_thread_id (thread_id)
-{
-}
-
-/* simple_diagnostic_event's dtor. */
-
-simple_diagnostic_event::~simple_diagnostic_event ()
-{
- free (m_desc);
-}
-
/* Print PATH by emitting a dummy "note" associated with it. */
DEBUG_FUNCTION
diff --git a/gcc/selftest-run-tests.cc b/gcc/selftest-run-tests.cc
index d8f5e4b34c6..3275db38ba9 100644
--- a/gcc/selftest-run-tests.cc
+++ b/gcc/selftest-run-tests.cc
@@ -103,6 +103,7 @@ selftest::run_tests ()
spellcheck_tree_cc_tests ();
tree_cfg_cc_tests ();
tree_diagnostic_path_cc_tests ();
+ simple_diagnostic_path_cc_tests ();
attribs_cc_tests ();
/* This one relies on most of the above. */
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 9e294ad1e5f..2d1aa91607e 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -250,6 +250,7 @@ extern void read_rtl_function_cc_tests ();
extern void rtl_tests_cc_tests ();
extern void sbitmap_cc_tests ();
extern void selftest_cc_tests ();
+extern void simple_diagnostic_path_cc_tests ();
extern void simplify_rtx_cc_tests ();
extern void spellcheck_cc_tests ();
extern void spellcheck_tree_cc_tests ();
diff --git a/gcc/simple-diagnostic-path.cc b/gcc/simple-diagnostic-path.cc
new file mode 100644
index 00000000000..3ec0e850985
--- /dev/null
+++ b/gcc/simple-diagnostic-path.cc
@@ -0,0 +1,228 @@
+/* Concrete classes for implementing diagnostic paths.
+ Copyright (C) 2019-2024 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#define INCLUDE_VECTOR
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "version.h"
+#include "demangle.h"
+#include "intl.h"
+#include "backtrace.h"
+#include "diagnostic.h"
+#include "simple-diagnostic-path.h"
+#include "selftest.h"
+
+/* class simple_diagnostic_path : public diagnostic_path. */
+
+simple_diagnostic_path::simple_diagnostic_path (pretty_printer *event_pp)
+: m_event_pp (event_pp),
+ m_localize_events (true)
+{
+ add_thread ("main");
+}
+
+/* Implementation of diagnostic_path::num_events vfunc for
+ simple_diagnostic_path: simply get the number of events in the vec. */
+
+unsigned
+simple_diagnostic_path::num_events () const
+{
+ return m_events.length ();
+}
+
+/* Implementation of diagnostic_path::get_event vfunc for
+ simple_diagnostic_path: simply return the event in the vec. */
+
+const diagnostic_event &
+simple_diagnostic_path::get_event (int idx) const
+{
+ return *m_events[idx];
+}
+
+unsigned
+simple_diagnostic_path::num_threads () const
+{
+ return m_threads.length ();
+}
+
+const diagnostic_thread &
+simple_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const
+{
+ return *m_threads[idx];
+}
+
+diagnostic_thread_id_t
+simple_diagnostic_path::add_thread (const char *name)
+{
+ m_threads.safe_push (new simple_diagnostic_thread (name));
+ return m_threads.length () - 1;
+}
+
+/* Add an event to this path at LOC within function FNDECL at
+ stack depth DEPTH.
+
+ Use m_context's printer to format FMT, as the text of the new
+ event. Localize FMT iff m_localize_events is set.
+
+ Return the id of the new event. */
+
+diagnostic_event_id_t
+simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
+ const char *fmt, ...)
+{
+ pretty_printer *pp = m_event_pp;
+ pp_clear_output_area (pp);
+
+ rich_location rich_loc (line_table, UNKNOWN_LOCATION);
+
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ text_info ti (m_localize_events ? _(fmt) : fmt,
+ &ap, 0, nullptr, &rich_loc);
+ pp_format (pp, &ti);
+ pp_output_formatted_text (pp);
+
+ va_end (ap);
+
+ simple_diagnostic_event *new_event
+ = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
+ m_events.safe_push (new_event);
+
+ pp_clear_output_area (pp);
+
+ return diagnostic_event_id_t (m_events.length () - 1);
+}
+
+diagnostic_event_id_t
+simple_diagnostic_path::add_thread_event (diagnostic_thread_id_t thread_id,
+ location_t loc,
+ tree fndecl,
+ int depth,
+ const char *fmt, ...)
+{
+ pretty_printer *pp = m_event_pp;
+ pp_clear_output_area (pp);
+
+ rich_location rich_loc (line_table, UNKNOWN_LOCATION);
+
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ text_info ti (_(fmt), &ap, 0, nullptr, &rich_loc);
+
+ pp_format (pp, &ti);
+ pp_output_formatted_text (pp);
+
+ va_end (ap);
+
+ simple_diagnostic_event *new_event
+ = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp),
+ thread_id);
+ m_events.safe_push (new_event);
+
+ pp_clear_output_area (pp);
+
+ return diagnostic_event_id_t (m_events.length () - 1);
+}
+
+/* Mark the most recent event on this path (which must exist) as being
+ connected to the next one to be added. */
+
+void
+simple_diagnostic_path::connect_to_next_event ()
+{
+ gcc_assert (m_events.length () > 0);
+ m_events[m_events.length () - 1]->connect_to_next_event ();
+}
+
+/* struct simple_diagnostic_event. */
+
+/* simple_diagnostic_event's ctor. */
+
+simple_diagnostic_event::
+simple_diagnostic_event (location_t loc,
+ tree fndecl,
+ 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_connected_to_next_event (false),
+ m_thread_id (thread_id)
+{
+}
+
+/* simple_diagnostic_event's dtor. */
+
+simple_diagnostic_event::~simple_diagnostic_event ()
+{
+ free (m_desc);
+}
+
+#if CHECKING_P
+
+namespace selftest {
+
+static void
+test_intraprocedural_path (pretty_printer *event_pp)
+{
+ tree fntype_void_void
+ = build_function_type_array (void_type_node, 0, NULL);
+ tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);
+
+ simple_diagnostic_path path (event_pp);
+ path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "first %qs", "free");
+ path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "double %qs", "free");
+
+ ASSERT_EQ (path.num_events (), 2);
+ ASSERT_EQ (path.num_threads (), 1);
+ ASSERT_FALSE (path.interprocedural_p ());
+ ASSERT_STREQ (path.get_event (0).get_desc (false).get (), "first `free'");
+ ASSERT_STREQ (path.get_event (1).get_desc (false).get (), "double `free'");
+}
+
+/* Run all of the selftests within this file. */
+
+void
+simple_diagnostic_path_cc_tests ()
+{
+ /* In a few places we use the global dc's printer to determine
+ colorization so ensure this off during the tests. */
+ const bool saved_show_color = pp_show_color (global_dc->printer);
+ pp_show_color (global_dc->printer) = false;
+
+ auto_fix_quotes fix_quotes;
+ std::unique_ptr<pretty_printer> event_pp
+ = std::unique_ptr<pretty_printer> (global_dc->printer->clone ());
+
+ test_intraprocedural_path (event_pp.get ());
+
+ pp_show_color (global_dc->printer) = saved_show_color;
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
diff --git a/gcc/simple-diagnostic-path.h b/gcc/simple-diagnostic-path.h
new file mode 100644
index 00000000000..5fbed158f15
--- /dev/null
+++ b/gcc/simple-diagnostic-path.h
@@ -0,0 +1,130 @@
+/* Concrete classes for implementing diagnostic paths.
+ Copyright (C) 2019-2024 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_SIMPLE_DIAGNOSTIC_PATH_H
+#define GCC_SIMPLE_DIAGNOSTIC_PATH_H
+
+#include "diagnostic-path.h"
+
+/* Concrete subclasses of the abstract base classes
+ declared in diagnostic-path.h. */
+
+/* A simple implementation of diagnostic_event. */
+
+class simple_diagnostic_event : public diagnostic_event
+{
+ public:
+ simple_diagnostic_event (location_t loc, tree fndecl, int depth,
+ const char *desc,
+ diagnostic_thread_id_t thread_id = 0);
+ ~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
+ {
+ return label_text::borrow (m_desc);
+ }
+ const logical_location *get_logical_location () const final override
+ {
+ return NULL;
+ }
+ meaning get_meaning () const final override
+ {
+ return meaning ();
+ }
+ bool connect_to_next_event_p () const final override
+ {
+ return m_connected_to_next_event;
+ }
+ diagnostic_thread_id_t get_thread_id () const final override
+ {
+ return m_thread_id;
+ }
+
+ void connect_to_next_event ()
+ {
+ m_connected_to_next_event = true;
+ }
+
+ private:
+ location_t m_loc;
+ tree m_fndecl;
+ int m_depth;
+ char *m_desc; // has been i18n-ed and formatted
+ bool m_connected_to_next_event;
+ diagnostic_thread_id_t m_thread_id;
+};
+
+/* A simple implementation of diagnostic_thread. */
+
+class simple_diagnostic_thread : public diagnostic_thread
+{
+public:
+ simple_diagnostic_thread (const char *name) : m_name (name) {}
+ label_text get_name (bool) const final override
+ {
+ return label_text::borrow (m_name);
+ }
+
+private:
+ const char *m_name; // has been i18n-ed and formatted
+};
+
+/* A simple implementation of diagnostic_path, as a vector of
+ simple_diagnostic_event instances. */
+
+class simple_diagnostic_path : public diagnostic_path
+{
+ public:
+ simple_diagnostic_path (pretty_printer *event_pp);
+
+ unsigned num_events () const final override;
+ const diagnostic_event & get_event (int idx) const final override;
+ unsigned num_threads () const final override;
+ const diagnostic_thread &
+ get_thread (diagnostic_thread_id_t) const final override;
+
+ diagnostic_thread_id_t add_thread (const char *name);
+
+ diagnostic_event_id_t add_event (location_t loc, tree fndecl, int depth,
+ const char *fmt, ...)
+ ATTRIBUTE_GCC_DIAG(5,6);
+ diagnostic_event_id_t
+ add_thread_event (diagnostic_thread_id_t thread_id,
+ location_t loc, tree fndecl, int depth,
+ const char *fmt, ...)
+ ATTRIBUTE_GCC_DIAG(6,7);
+
+ void connect_to_next_event ();
+
+ void disable_event_localization () { m_localize_events = false; }
+
+ private:
+ auto_delete_vec<simple_diagnostic_thread> m_threads;
+ auto_delete_vec<simple_diagnostic_event> m_events;
+
+ /* (for use by add_event). */
+ pretty_printer *m_event_pp;
+ bool m_localize_events;
+};
+
+#endif /* ! GCC_SIMPLE_DIAGNOSTIC_PATH_H */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
index bf665005c8b..efa4ec475ab 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
@@ -38,6 +38,7 @@
#include "print-tree.h"
#include "gcc-rich-location.h"
#include "cgraph.h"
+#include "simple-diagnostic-path.h"
int plugin_is_GPL_compatible;
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index f82ef305c06..a9dd40cbd9d 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "intl.h"
#include "diagnostic-path.h"
+#include "simple-diagnostic-path.h"
#include "json.h"
#include "gcc-rich-location.h"
#include "diagnostic-color.h"
--
2.26.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/7] diagnostics: eliminate "tree" from diagnostic_{event,path}
2024-06-18 15:08 [pushed 0/7] diagnostics: remove "tree" dependency from diagnostic paths David Malcolm
2024-06-18 15:08 ` [PATCH 1/7] diagnostics: move simple_diagnostic_{path,thread,event} to their own .h/cc David Malcolm
@ 2024-06-18 15:08 ` David Malcolm
2024-06-18 15:08 ` [PATCH 3/7] diagnostics: remove tree usage from tree-diagnostic-path.cc David Malcolm
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: David Malcolm @ 2024-06-18 15:08 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
This patch eliminates the use of "tree" from diagnostic_{event,path} in
favor of const logical_location *.
No functional change intended.
gcc/analyzer/ChangeLog:
* checker-event.h (checker_event::fndecl): Drop "final" and
"override", converting from a vfunc implementation to a plain
accessor.
* checker-path.cc (checker_path::same_function_p): New.
* checker-path.h (checker_path::same_function_p): New decl.
gcc/ChangeLog:
* diagnostic.cc: Include "logical-location.h".
(diagnostic_path::get_first_event_in_a_function): Fix typo in
leading comment. Rewrite to use logical_location rather than
tree. Drop test on stack depth.
(diagnostic_path::interprocedural_p): Rewrite to use
logical_location rather than tree.
(logical_location::function_p): New.
* diagnostic-path.h (diagnostic_event::get_fndecl): Eliminate
vfunc.
(diagnostic_path::same_function_p): New pure virtual func.
* logical-location.h (logical_location::get_name_for_path_output):
New pure virtual func.
* simple-diagnostic-path.cc
(simple_diagnostic_path::same_function_p): New.
(simple_diagnostic_event::simple_diagnostic_event): Initialize
m_logical_loc.
* simple-diagnostic-path.h: Include "tree-logical-location.h".
(simple_diagnostic_event::get_fndecl): Convert from a vfunc
implementation to an accessor.
(simple_diagnostic_event::get_logical_location): Use
m_logical_loc.
(simple_diagnostic_event::m_logical_loc): New field.
(simple_diagnostic_path::same_function_p): New decl.
* tree-diagnostic-path.cc: Move pragma disabling -Wformat-diag to
cover the whole file.
(can_consolidate_events): Add params "path", "ev1_idx", and
"ev2_idx". Rewrite to use diagnostic_path::same_function_p rather
than tree.
(per_thread_summary::per_thread_summary): Add "path" param
(per_thread_summary::m_path): New field.
(event_range::event_range): Update for conversion of m_fndecl to
m_logical_loc.
(event_range::maybe_add_event): Rename param "idx" to
"new_ev_idx". Update call to can_consolidate_events to pass in
"m_path", "m_start_idx", and "new_ev_idx".
(event_range::m_fndecl): Replace with...
(event_range::m_logical_loc): ...this.
(path_summary::get_or_create_events_for_thread_id): Pass "path" to
per_thread_summary ctor.
(per_thread_summary::interprocedural_p): Rewrite to use
diagnostic_path::same_function_p rather than tree.
(print_fndecl): Delete.
(thread_event_printer::print_swimlane_for_event_range): Update for
conversion from tree to logical_location.
(default_tree_diagnostic_path_printer): Likewise.
(default_tree_make_json_for_path): Likewise.
* tree-logical-location.cc: Include "intl.h".
(compiler_logical_location::get_name_for_tree_for_path_output):
New.
(tree_logical_location::get_name_for_path_output): New.
(current_fndecl_logical_location::get_name_for_path_output): New.
* tree-logical-location.h
(compiler_logical_location::get_name_for_tree_for_path_output):
New decl.
(tree_logical_location::get_name_for_path_output): New decl.
(current_fndecl_logical_location::get_name_for_path_output): New
decl.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/analyzer/checker-event.h | 2 +-
gcc/analyzer/checker-path.cc | 8 +++
gcc/analyzer/checker-path.h | 4 ++
gcc/diagnostic-path.h | 10 +++-
gcc/diagnostic.cc | 47 ++++++++++++----
gcc/logical-location.h | 5 ++
gcc/simple-diagnostic-path.cc | 11 +++-
gcc/simple-diagnostic-path.h | 13 ++++-
gcc/tree-diagnostic-path.cc | 103 +++++++++++++++++-----------------
gcc/tree-logical-location.cc | 25 +++++++++
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 d0935aca985..4343641f441 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 c8361915ad9..cfbbc0b25f3 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 162ebb3f0d8..1aa56d27927 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 958eb725322..7497b0a7199 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 a7acde50ab8..844eb8e1048 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 abe2c3a648e..c3b72081135 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 3ec0e850985..7c47b830934 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 5fbed158f15..5147df5185b 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 a9dd40cbd9d..4287b90d5dd 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 0333b318642..ca8b34a42d3 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 feaad6ed899..8634f3a49c0 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. */
--
2.26.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/7] diagnostics: remove tree usage from tree-diagnostic-path.cc
2024-06-18 15:08 [pushed 0/7] diagnostics: remove "tree" dependency from diagnostic paths David Malcolm
2024-06-18 15:08 ` [PATCH 1/7] diagnostics: move simple_diagnostic_{path,thread,event} to their own .h/cc David Malcolm
2024-06-18 15:08 ` [PATCH 2/7] diagnostics: eliminate "tree" from diagnostic_{event,path} David Malcolm
@ 2024-06-18 15:08 ` David Malcolm
2024-06-18 15:08 ` [PATCH 4/7] diagnostics: eliminate diagnostic_context::m_make_json_for_path David Malcolm
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: David Malcolm @ 2024-06-18 15:08 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
No functional change intended.
gcc/ChangeLog:
* Makefile.in (OBJS): Add selftest-diagnostic-path.o and
selftest-logical-location.o.
* logical-location.h: Include "label-text.h".
(class logical_location): Update leading comment.
* selftest-diagnostic-path.cc: New file, adapted from
simple-diagnostic-path.cc and from material in
tree-diagnostic-path.cc.
* selftest-diagnostic-path.h: New file, adapted from
simple-diagnostic-path.h and from material in
tree-diagnostic-path.cc.
* selftest-logical-location.cc: New file.
* selftest-logical-location.h: New file.
* tree-diagnostic-path.cc: Remove includes of "tree-pretty-print.h",
"langhooks.h", and "simple-diagnostic-path.h". Add include of
"selftest-diagnostic-path.h".
(class test_diagnostic_path): Delete, in favor of new
implementation in selftest-diagnostic-path.{h,cc}, which is
directly derived from diagnostic_path, rather than from
simple_diagnostic_path.
(selftest::test_intraprocedural_path): Eliminate tree usage,
via change to test_diagnostic_path, using strings rather than
function_decls for identifying functions in the test.
(selftest::test_interprocedural_path_1): Likewise.
(selftest::test_interprocedural_path_2): Likewise.
(selftest::test_recursion): Likewise.
(selftest::test_control_flow_1): Likewise.
(selftest::test_control_flow_2): Likewise.
(selftest::test_control_flow_3): Likewise.
(selftest::assert_cfg_edge_path_streq): Likewise.
(selftest::test_control_flow_5): Likewise.
(selftest::test_control_flow_6): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/Makefile.in | 2 +
gcc/logical-location.h | 5 +-
gcc/selftest-diagnostic-path.cc | 233 +++++++++++++++++++++++++++++++
gcc/selftest-diagnostic-path.h | 163 +++++++++++++++++++++
gcc/selftest-logical-location.cc | 71 ++++++++++
gcc/selftest-logical-location.h | 58 ++++++++
gcc/tree-diagnostic-path.cc | 161 +++++++--------------
7 files changed, 580 insertions(+), 113 deletions(-)
create mode 100644 gcc/selftest-diagnostic-path.cc
create mode 100644 gcc/selftest-diagnostic-path.h
create mode 100644 gcc/selftest-logical-location.cc
create mode 100644 gcc/selftest-logical-location.h
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 35f259da858..a2799b8d826 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1700,6 +1700,8 @@ OBJS = \
ubsan.o \
sanopt.o \
sancov.o \
+ selftest-diagnostic-path.o \
+ selftest-logical-location.o \
simple-diagnostic-path.o \
tree-call-cdce.o \
tree-cfg.o \
diff --git a/gcc/logical-location.h b/gcc/logical-location.h
index c3b72081135..bba21087786 100644
--- a/gcc/logical-location.h
+++ b/gcc/logical-location.h
@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_LOGICAL_LOCATION_H
#define GCC_LOGICAL_LOCATION_H
+#include "label-text.h"
+
/* An enum for discriminating between different kinds of logical location
for a diagnostic.
@@ -46,7 +48,8 @@ enum logical_location_kind
- "within function 'foo'", or
- "within method 'bar'",
but *without* requiring knowledge of trees
- (see tree-logical-location.h for subclasses relating to trees). */
+ (see tree-logical-location.h for concrete subclasses relating to trees,
+ and selftest-logical-location.h for a concrete subclass for selftests). */
class logical_location
{
diff --git a/gcc/selftest-diagnostic-path.cc b/gcc/selftest-diagnostic-path.cc
new file mode 100644
index 00000000000..6d21f2e5599
--- /dev/null
+++ b/gcc/selftest-diagnostic-path.cc
@@ -0,0 +1,233 @@
+/* Concrete classes for selftests involving diagnostic paths.
+ Copyright (C) 2019-2024 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+#include "config.h"
+#define INCLUDE_VECTOR
+#include "system.h"
+#include "coretypes.h"
+#include "version.h"
+#include "demangle.h"
+#include "backtrace.h"
+#include "diagnostic.h"
+#include "selftest-diagnostic-path.h"
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* class test_diagnostic_path : public diagnostic_path. */
+
+test_diagnostic_path::test_diagnostic_path (pretty_printer *event_pp)
+: m_event_pp (event_pp)
+{
+ add_thread ("main");
+}
+
+/* Implementation of diagnostic_path::num_events vfunc for
+ test_diagnostic_path: simply get the number of events in the vec. */
+
+unsigned
+test_diagnostic_path::num_events () const
+{
+ return m_events.length ();
+}
+
+/* Implementation of diagnostic_path::get_event vfunc for
+ test_diagnostic_path: simply return the event in the vec. */
+
+const diagnostic_event &
+test_diagnostic_path::get_event (int idx) const
+{
+ return *m_events[idx];
+}
+
+unsigned
+test_diagnostic_path::num_threads () const
+{
+ return m_threads.length ();
+}
+
+const diagnostic_thread &
+test_diagnostic_path::get_thread (diagnostic_thread_id_t idx) const
+{
+ return *m_threads[idx];
+}
+
+bool
+test_diagnostic_path::same_function_p (int event_idx_a,
+ int event_idx_b) const
+{
+ const char *name_a = m_events[event_idx_a]->get_function_name ();
+ const char *name_b = m_events[event_idx_b]->get_function_name ();
+
+ if (name_a && name_b)
+ return 0 == strcmp (name_a, name_b);
+ return name_a == name_b;
+}
+
+diagnostic_thread_id_t
+test_diagnostic_path::add_thread (const char *name)
+{
+ m_threads.safe_push (new test_diagnostic_thread (name));
+ return m_threads.length () - 1;
+}
+
+/* Add an event to this path at LOC within function FNDECL at
+ stack depth DEPTH.
+
+ Use m_context's printer to format FMT, as the text of the new
+ event.
+
+ Return the id of the new event. */
+
+diagnostic_event_id_t
+test_diagnostic_path::add_event (location_t loc,
+ const char *funcname,
+ int depth,
+ const char *fmt, ...)
+{
+ pretty_printer *pp = m_event_pp;
+ pp_clear_output_area (pp);
+
+ rich_location rich_loc (line_table, UNKNOWN_LOCATION);
+
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ /* No localization is done on FMT. */
+ text_info ti (fmt, &ap, 0, nullptr, &rich_loc);
+ pp_format (pp, &ti);
+ pp_output_formatted_text (pp);
+
+ va_end (ap);
+
+ test_diagnostic_event *new_event
+ = new test_diagnostic_event (loc, funcname, depth, pp_formatted_text (pp));
+ m_events.safe_push (new_event);
+
+ pp_clear_output_area (pp);
+
+ return diagnostic_event_id_t (m_events.length () - 1);
+}
+
+diagnostic_event_id_t
+test_diagnostic_path::add_thread_event (diagnostic_thread_id_t thread_id,
+ location_t loc,
+ const char *funcname,
+ int depth,
+ const char *fmt, ...)
+{
+ pretty_printer *pp = m_event_pp;
+ pp_clear_output_area (pp);
+
+ rich_location rich_loc (line_table, UNKNOWN_LOCATION);
+
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ /* No localization is done on FMT. */
+ text_info ti (fmt, &ap, 0, nullptr, &rich_loc);
+
+ pp_format (pp, &ti);
+ pp_output_formatted_text (pp);
+
+ va_end (ap);
+
+ test_diagnostic_event *new_event
+ = new test_diagnostic_event (loc, funcname, depth, pp_formatted_text (pp),
+ thread_id);
+ m_events.safe_push (new_event);
+
+ pp_clear_output_area (pp);
+
+ return diagnostic_event_id_t (m_events.length () - 1);
+}
+
+/* Mark the most recent event on this path (which must exist) as being
+ connected to the next one to be added. */
+
+void
+test_diagnostic_path::connect_to_next_event ()
+{
+ gcc_assert (m_events.length () > 0);
+ m_events[m_events.length () - 1]->connect_to_next_event ();
+}
+
+void
+test_diagnostic_path::add_entry (const char *callee_name,
+ int stack_depth,
+ diagnostic_thread_id_t thread_id)
+{
+ add_thread_event (thread_id, UNKNOWN_LOCATION, callee_name, stack_depth,
+ "entering %qs", callee_name);
+}
+
+void
+test_diagnostic_path::add_return (const char *caller_name,
+ int stack_depth,
+ diagnostic_thread_id_t thread_id)
+{
+ add_thread_event (thread_id, UNKNOWN_LOCATION, caller_name, stack_depth,
+ "returning to %qs", caller_name);
+}
+
+void
+test_diagnostic_path::add_call (const char *caller_name,
+ int caller_stack_depth,
+ const char *callee_name,
+ diagnostic_thread_id_t thread_id)
+{
+ add_thread_event (thread_id, UNKNOWN_LOCATION,
+ caller_name, caller_stack_depth,
+ "calling %qs", callee_name);
+ add_entry (callee_name, caller_stack_depth + 1, thread_id);
+}
+
+/* struct test_diagnostic_event. */
+
+/* test_diagnostic_event's ctor. */
+
+test_diagnostic_event::
+test_diagnostic_event (location_t loc,
+ const char *funcname,
+ int depth,
+ const char *desc,
+ diagnostic_thread_id_t thread_id)
+: m_loc (loc),
+ m_logical_loc (LOGICAL_LOCATION_KIND_FUNCTION, funcname),
+ m_depth (depth), m_desc (xstrdup (desc)),
+ m_connected_to_next_event (false),
+ m_thread_id (thread_id)
+{
+}
+
+/* test_diagnostic_event's dtor. */
+
+test_diagnostic_event::~test_diagnostic_event ()
+{
+ free (m_desc);
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
diff --git a/gcc/selftest-diagnostic-path.h b/gcc/selftest-diagnostic-path.h
new file mode 100644
index 00000000000..51786a0f589
--- /dev/null
+++ b/gcc/selftest-diagnostic-path.h
@@ -0,0 +1,163 @@
+/* Concrete classes for selftests involving diagnostic paths.
+ Copyright (C) 2019-2024 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_SELFTEST_DIAGNOSTIC_PATH_H
+#define GCC_SELFTEST_DIAGNOSTIC_PATH_H
+
+#include "diagnostic-path.h"
+#include "selftest-logical-location.h"
+
+/* The selftest code should entirely disappear in a production
+ configuration, hence we guard all of it with #if CHECKING_P. */
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Concrete subclasses of the abstract base classes
+ declared in diagnostic-path.h for use in selftests.
+
+ This code should have no dependency on "tree". */
+
+/* An implementation of diagnostic_event. */
+
+class test_diagnostic_event : public diagnostic_event
+{
+ public:
+ test_diagnostic_event (location_t loc, const char *funcname, int depth,
+ const char *desc,
+ diagnostic_thread_id_t thread_id = 0);
+ ~test_diagnostic_event ();
+
+ location_t get_location () const final override { return m_loc; }
+ int get_stack_depth () const final override { return m_depth; }
+ label_text get_desc (bool) const final override
+ {
+ return label_text::borrow (m_desc);
+ }
+ const logical_location *get_logical_location () const final override
+ {
+ if (m_logical_loc.get_name ())
+ return &m_logical_loc;
+ else
+ return nullptr;
+ }
+ meaning get_meaning () const final override
+ {
+ return meaning ();
+ }
+ bool connect_to_next_event_p () const final override
+ {
+ return m_connected_to_next_event;
+ }
+ diagnostic_thread_id_t get_thread_id () const final override
+ {
+ return m_thread_id;
+ }
+
+ void connect_to_next_event ()
+ {
+ m_connected_to_next_event = true;
+ }
+
+ const char *get_function_name () const
+ {
+ return m_logical_loc.get_name ();
+ }
+
+ private:
+ location_t m_loc;
+ test_logical_location m_logical_loc;
+ int m_depth;
+ char *m_desc; // has been formatted; doesn't get i18n-ed
+ bool m_connected_to_next_event;
+ diagnostic_thread_id_t m_thread_id;
+};
+
+/* A simple implementation of diagnostic_thread. */
+
+class test_diagnostic_thread : public diagnostic_thread
+{
+public:
+ test_diagnostic_thread (const char *name) : m_name (name) {}
+ label_text get_name (bool) const final override
+ {
+ return label_text::borrow (m_name);
+ }
+
+private:
+ const char *m_name; // has been i18n-ed and formatted
+};
+
+/* A concrete subclass of diagnostic_path for implementing selftests
+ - a vector of test_diagnostic_event instances
+ - adds member functions for adding test event
+ - does no translation of its events
+ - has no dependency on "tree". */
+
+class test_diagnostic_path : public diagnostic_path
+{
+ public:
+ test_diagnostic_path (pretty_printer *event_pp);
+
+ unsigned num_events () const final override;
+ const diagnostic_event & get_event (int idx) const final override;
+ 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);
+
+ diagnostic_event_id_t add_event (location_t loc, const char *funcname, int depth,
+ const char *fmt, ...)
+ ATTRIBUTE_GCC_DIAG(5,6);
+ diagnostic_event_id_t
+ add_thread_event (diagnostic_thread_id_t thread_id,
+ location_t loc, const char *funcname, int depth,
+ const char *fmt, ...)
+ ATTRIBUTE_GCC_DIAG(6,7);
+
+ void connect_to_next_event ();
+
+ void add_entry (const char *callee_name, int stack_depth,
+ diagnostic_thread_id_t thread_id = 0);
+ void add_return (const char *caller_name, int stack_depth,
+ diagnostic_thread_id_t thread_id = 0);
+ void add_call (const char *caller_name,
+ int caller_stack_depth,
+ const char *callee_name,
+ diagnostic_thread_id_t thread_id = 0);
+
+ private:
+ auto_delete_vec<test_diagnostic_thread> m_threads;
+ auto_delete_vec<test_diagnostic_event> m_events;
+
+ /* (for use by add_event). */
+ pretty_printer *m_event_pp;
+};
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
+
+#endif /* ! GCC_SELFTEST_DIAGNOSTIC_PATH_H */
diff --git a/gcc/selftest-logical-location.cc b/gcc/selftest-logical-location.cc
new file mode 100644
index 00000000000..8017672afa7
--- /dev/null
+++ b/gcc/selftest-logical-location.cc
@@ -0,0 +1,71 @@
+/* Concrete subclass of logical_location for use in selftests.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "selftest-logical-location.h"
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* class test_logical_location : public logical_location. */
+
+test_logical_location::test_logical_location (enum logical_location_kind kind,
+ const char *name)
+: m_kind (kind),
+ m_name (name)
+{
+}
+
+const char *
+test_logical_location::get_short_name () const
+{
+ return m_name;
+}
+
+const char *
+test_logical_location::get_name_with_scope () const
+{
+ return m_name;
+}
+
+const char *
+test_logical_location::get_internal_name () const
+{
+ return m_name;
+}
+
+enum logical_location_kind
+test_logical_location::get_kind () const
+{
+ return m_kind;
+}
+
+label_text
+test_logical_location::get_name_for_path_output () const
+{
+ return label_text::borrow (m_name);
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
diff --git a/gcc/selftest-logical-location.h b/gcc/selftest-logical-location.h
new file mode 100644
index 00000000000..819e111851e
--- /dev/null
+++ b/gcc/selftest-logical-location.h
@@ -0,0 +1,58 @@
+/* Concrete subclass of logical_location for use in selftests.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_SELFTEST_LOGICAL_LOCATION_H
+#define GCC_SELFTEST_LOGICAL_LOCATION_H
+
+#include "logical-location.h"
+
+/* The selftest code should entirely disappear in a production
+ configuration, hence we guard all of it with #if CHECKING_P. */
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Concrete subclass of logical_location for use in selftests. */
+
+class test_logical_location : public logical_location
+{
+public:
+ test_logical_location (enum logical_location_kind kind,
+ const char *name);
+ virtual const char *get_short_name () const final override;
+ virtual const char *get_name_with_scope () const final override;
+ virtual const char *get_internal_name () const final override;
+ virtual enum logical_location_kind get_kind () const final override;
+ virtual label_text get_name_for_path_output () const final override;
+
+ const char *get_name () const { return m_name; }
+
+ private:
+ enum logical_location_kind m_kind;
+ const char *m_name;
+};
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
+
+
+#endif /* GCC_SELFTEST_LOGICAL_LOCATION_H. */
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index 4287b90d5dd..39a85d33015 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -27,13 +27,9 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "diagnostic.h"
-#include "tree-pretty-print.h"
-#include "gimple-pretty-print.h"
#include "tree-diagnostic.h"
-#include "langhooks.h"
#include "intl.h"
#include "diagnostic-path.h"
-#include "simple-diagnostic-path.h"
#include "json.h"
#include "gcc-rich-location.h"
#include "diagnostic-color.h"
@@ -41,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-label-effects.h"
#include "selftest.h"
#include "selftest-diagnostic.h"
+#include "selftest-diagnostic-path.h"
#include "text-art/theme.h"
/* Disable warnings about missing quoting in GCC diagnostics for the print
@@ -1013,38 +1010,6 @@ path_events_have_column_data_p (const diagnostic_path &path)
return true;
}
-/* A subclass of simple_diagnostic_path that adds member functions
- for adding test events and suppresses translation of these events. */
-
-class test_diagnostic_path : public simple_diagnostic_path
-{
- public:
- test_diagnostic_path (pretty_printer *event_pp)
- : simple_diagnostic_path (event_pp)
- {
- disable_event_localization ();
- }
-
- void add_entry (tree fndecl, int stack_depth)
- {
- add_event (UNKNOWN_LOCATION, fndecl, stack_depth,
- "entering %qE", fndecl);
- }
-
- void add_return (tree fndecl, int stack_depth)
- {
- add_event (UNKNOWN_LOCATION, fndecl, stack_depth,
- "returning to %qE", fndecl);
- }
-
- void add_call (tree caller, int caller_stack_depth, tree callee)
- {
- add_event (UNKNOWN_LOCATION, caller, caller_stack_depth,
- "calling %qE", callee);
- add_entry (callee, caller_stack_depth + 1);
- }
-};
-
/* Verify that empty paths are handled gracefully. */
static void
@@ -1067,13 +1032,10 @@ test_empty_path (pretty_printer *event_pp)
static void
test_intraprocedural_path (pretty_printer *event_pp)
{
- tree fntype_void_void
- = build_function_type_array (void_type_node, 0, NULL);
- tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);
-
test_diagnostic_path path (event_pp);
- path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "first %qs", "free");
- path.add_event (UNKNOWN_LOCATION, fndecl_foo, 0, "double %qs", "free");
+ const char *const funcname = "foo";
+ path.add_event (UNKNOWN_LOCATION, funcname, 0, "first %qs", "free");
+ path.add_event (UNKNOWN_LOCATION, funcname, 0, "double %qs", "free");
ASSERT_FALSE (path.interprocedural_p ());
@@ -1093,33 +1055,20 @@ test_intraprocedural_path (pretty_printer *event_pp)
static void
test_interprocedural_path_1 (pretty_printer *event_pp)
{
- /* Build fndecls. The types aren't quite right, but that
- doesn't matter for the purposes of this test. */
- tree fntype_void_void
- = build_function_type_array (void_type_node, 0, NULL);
- tree fndecl_test = build_fn_decl ("test", fntype_void_void);
- tree fndecl_make_boxed_int
- = build_fn_decl ("make_boxed_int", fntype_void_void);
- tree fndecl_wrapped_malloc
- = build_fn_decl ("wrapped_malloc", fntype_void_void);
- tree fndecl_free_boxed_int
- = build_fn_decl ("free_boxed_int", fntype_void_void);
- tree fndecl_wrapped_free
- = build_fn_decl ("wrapped_free", fntype_void_void);
-
test_diagnostic_path path (event_pp);
- path.add_entry (fndecl_test, 0);
- path.add_call (fndecl_test, 0, fndecl_make_boxed_int);
- path.add_call (fndecl_make_boxed_int, 1, fndecl_wrapped_malloc);
- path.add_event (UNKNOWN_LOCATION, fndecl_wrapped_malloc, 2, "calling malloc");
- path.add_return (fndecl_test, 0);
- path.add_call (fndecl_test, 0, fndecl_free_boxed_int);
- path.add_call (fndecl_free_boxed_int, 1, fndecl_wrapped_free);
- path.add_event (UNKNOWN_LOCATION, fndecl_wrapped_free, 2, "calling free");
- path.add_return (fndecl_test, 0);
- path.add_call (fndecl_test, 0, fndecl_free_boxed_int);
- path.add_call (fndecl_free_boxed_int, 1, fndecl_wrapped_free);
- path.add_event (UNKNOWN_LOCATION, fndecl_wrapped_free, 2, "calling free");
+ path.add_entry ("test", 0);
+ path.add_call ("test", 0, "make_boxed_int");
+ path.add_call ("make_boxed_int", 1, "wrapped_malloc");
+ path.add_event (UNKNOWN_LOCATION,
+ "wrapped_malloc", 2, "calling malloc");
+ path.add_return ("test", 0);
+ path.add_call ("test", 0, "free_boxed_int");
+ path.add_call ("free_boxed_int", 1, "wrapped_free");
+ path.add_event (UNKNOWN_LOCATION, "wrapped_free", 2, "calling free");
+ path.add_return ("test", 0);
+ path.add_call ("test", 0, "free_boxed_int");
+ path.add_call ("free_boxed_int", 1, "wrapped_free");
+ path.add_event (UNKNOWN_LOCATION, "wrapped_free", 2, "calling free");
ASSERT_EQ (path.num_events (), 18);
ASSERT_TRUE (path.interprocedural_p ());
@@ -1248,20 +1197,12 @@ test_interprocedural_path_1 (pretty_printer *event_pp)
static void
test_interprocedural_path_2 (pretty_printer *event_pp)
{
- /* Build fndecls. The types aren't quite right, but that
- doesn't matter for the purposes of this test. */
- tree fntype_void_void
- = build_function_type_array (void_type_node, 0, NULL);
- tree fndecl_foo = build_fn_decl ("foo", fntype_void_void);
- tree fndecl_bar = build_fn_decl ("bar", fntype_void_void);
- tree fndecl_baz = build_fn_decl ("baz", fntype_void_void);
-
test_diagnostic_path path (event_pp);
- path.add_entry (fndecl_foo, 0);
- path.add_call (fndecl_foo, 0, fndecl_bar);
- path.add_call (fndecl_bar, 1, fndecl_baz);
- path.add_return (fndecl_bar, 1);
- path.add_call (fndecl_bar, 1, fndecl_baz);
+ path.add_entry ("foo", 0);
+ path.add_call ("foo", 0, "bar");
+ path.add_call ("bar", 1, "baz");
+ path.add_return ("bar", 1);
+ path.add_call ("bar", 1, "baz");
ASSERT_EQ (path.num_events (), 8);
ASSERT_TRUE (path.interprocedural_p ());
@@ -1341,14 +1282,10 @@ test_interprocedural_path_2 (pretty_printer *event_pp)
static void
test_recursion (pretty_printer *event_pp)
{
- tree fntype_void_void
- = build_function_type_array (void_type_node, 0, NULL);
- tree fndecl_factorial = build_fn_decl ("factorial", fntype_void_void);
-
test_diagnostic_path path (event_pp);
- path.add_entry (fndecl_factorial, 0);
+ path.add_entry ("factorial", 0);
for (int depth = 0; depth < 3; depth++)
- path.add_call (fndecl_factorial, depth, fndecl_factorial);
+ path.add_call ("factorial", depth, "factorial");
ASSERT_EQ (path.num_events (), 7);
ASSERT_TRUE (path.interprocedural_p ());
@@ -1485,14 +1422,14 @@ test_control_flow_1 (const line_table_case &case_,
const location_t cfg_dest = t.get_line_and_column (5, 10);
test_diagnostic_path path (event_pp);
- path.add_event (conditional, NULL_TREE, 0,
+ path.add_event (conditional, nullptr, 0,
"following %qs branch (when %qs is NULL)...",
"false", "p");
path.connect_to_next_event ();
- path.add_event (cfg_dest, NULL_TREE, 0,
+ path.add_event (cfg_dest, nullptr, 0,
"...to here");
- path.add_event (cfg_dest, NULL_TREE, 0,
+ path.add_event (cfg_dest, nullptr, 0,
"dereference of NULL %qs",
"p");
@@ -1665,17 +1602,17 @@ test_control_flow_2 (const line_table_case &case_,
const location_t loop_body_end = t.get_line_and_columns (5, 5, 9, 17);
test_diagnostic_path path (event_pp);
- path.add_event (iter_test, NULL_TREE, 0, "infinite loop here");
+ path.add_event (iter_test, nullptr, 0, "infinite loop here");
- path.add_event (iter_test, NULL_TREE, 0, "looping from here...");
+ path.add_event (iter_test, nullptr, 0, "looping from here...");
path.connect_to_next_event ();
- path.add_event (loop_body_start, NULL_TREE, 0, "...to here");
+ path.add_event (loop_body_start, nullptr, 0, "...to here");
- path.add_event (loop_body_end, NULL_TREE, 0, "looping back...");
+ path.add_event (loop_body_end, nullptr, 0, "looping back...");
path.connect_to_next_event ();
- path.add_event (iter_test, NULL_TREE, 0, "...to here");
+ path.add_event (iter_test, nullptr, 0, "...to here");
if (!path_events_have_column_data_p (path))
return;
@@ -1751,17 +1688,17 @@ test_control_flow_3 (const line_table_case &case_,
const location_t iter_next = t.get_line_and_columns (3, 22, 24);
test_diagnostic_path path (event_pp);
- path.add_event (iter_test, NULL_TREE, 0, "infinite loop here");
+ path.add_event (iter_test, nullptr, 0, "infinite loop here");
- path.add_event (iter_test, NULL_TREE, 0, "looping from here...");
+ path.add_event (iter_test, nullptr, 0, "looping from here...");
path.connect_to_next_event ();
- path.add_event (iter_next, NULL_TREE, 0, "...to here");
+ path.add_event (iter_next, nullptr, 0, "...to here");
- path.add_event (iter_next, NULL_TREE, 0, "looping back...");
+ path.add_event (iter_next, nullptr, 0, "looping back...");
path.connect_to_next_event ();
- path.add_event (iter_test, NULL_TREE, 0, "...to here");
+ path.add_event (iter_test, nullptr, 0, "...to here");
if (!path_events_have_column_data_p (path))
return;
@@ -1816,10 +1753,10 @@ assert_cfg_edge_path_streq (const location &loc,
const char *expected_str)
{
test_diagnostic_path path (event_pp);
- path.add_event (src_loc, NULL_TREE, 0, "from here...");
+ path.add_event (src_loc, nullptr, 0, "from here...");
path.connect_to_next_event ();
- path.add_event (dst_loc, NULL_TREE, 0, "...to here");
+ path.add_event (dst_loc, nullptr, 0, "...to here");
if (!path_events_have_column_data_p (path))
return;
@@ -2120,27 +2057,27 @@ test_control_flow_5 (const line_table_case &case_,
test_diagnostic_path path (event_pp);
/* (1) */
- path.add_event (t.get_line_and_column (1, 6), NULL_TREE, 0,
+ path.add_event (t.get_line_and_column (1, 6), nullptr, 0,
"following %qs branch (when %qs is non-NULL)...",
"false", "arr");
path.connect_to_next_event ();
/* (2) */
- path.add_event (t.get_line_and_columns (4, 8, 10, 12), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (4, 8, 10, 12), nullptr, 0,
"...to here");
/* (3) */
- path.add_event (t.get_line_and_columns (4, 15, 17, 19), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (4, 15, 17, 19), nullptr, 0,
"following %qs branch (when %qs)...",
"true", "i < n");
path.connect_to_next_event ();
/* (4) */
- path.add_event (t.get_line_and_column (5, 13), NULL_TREE, 0,
+ path.add_event (t.get_line_and_column (5, 13), nullptr, 0,
"...to here");
/* (5) */
- path.add_event (t.get_line_and_columns (5, 33, 58), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (5, 33, 58), nullptr, 0,
"allocated here");
if (!path_events_have_column_data_p (path))
@@ -2208,27 +2145,27 @@ test_control_flow_6 (const line_table_case &case_,
test_diagnostic_path path (event_pp);
/* (1) */
- path.add_event (t.get_line_and_columns (6, 25, 35), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (6, 25, 35), nullptr, 0,
"allocated here");
/* (2) */
- path.add_event (t.get_line_and_columns (8, 13, 14, 17), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (8, 13, 14, 17), nullptr, 0,
"following %qs branch (when %qs)...",
"true", "i <= 254");
path.connect_to_next_event ();
/* (3) */
- path.add_event (t.get_line_and_columns (9, 5, 15, 17), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (9, 5, 15, 17), nullptr, 0,
"...to here");
/* (4) */
- path.add_event (t.get_line_and_columns (8, 13, 14, 17), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (8, 13, 14, 17), nullptr, 0,
"following %qs branch (when %qs)...",
"true", "i <= 254");
path.connect_to_next_event ();
/* (5) */
- path.add_event (t.get_line_and_columns (9, 5, 15, 17), NULL_TREE, 0,
+ path.add_event (t.get_line_and_columns (9, 5, 15, 17), nullptr, 0,
"...to here");
if (!path_events_have_column_data_p (path))
--
2.26.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/7] diagnostics: eliminate diagnostic_context::m_make_json_for_path
2024-06-18 15:08 [pushed 0/7] diagnostics: remove "tree" dependency from diagnostic paths David Malcolm
` (2 preceding siblings ...)
2024-06-18 15:08 ` [PATCH 3/7] diagnostics: remove tree usage from tree-diagnostic-path.cc David Malcolm
@ 2024-06-18 15:08 ` David Malcolm
2024-06-18 15:08 ` [PATCH 5/7] diagnostics: introduce diagnostic-macro-unwinding.h/cc David Malcolm
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: David Malcolm @ 2024-06-18 15:08 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
Now that the path-handling code for json_output_format no longer
needs "tree", and thus can be in OBJS-libcommon we can move it
from tree-diagnostic-path.cc to diagnostic-format-json.cc where it
should have been all along.
No functional change intended.
gcc/ChangeLog:
* diagnostic-format-json.cc: Include "diagnostic-path.h" and
"logical-location.h".
(make_json_for_path): Move tree-diagnostic-path.cc's
default_tree_make_json_for_path here, renaming it and making it
static.
(json_output_format::on_end_diagnostic): Replace call of
m_context's m_make_json_for_path callback with a direct call to
make_json_for_path.
* diagnostic.h (diagnostic_context::m_make_json_for_path): Drop
field.
* tree-diagnostic-path.cc: Drop include of "json.h".
(default_tree_make_json_for_path): Rename to make_json_for_path
and move to diagnostic-format-json.cc.
* tree-diagnostic.cc (tree_diagnostics_defaults): Drop
initialization of m_make_json_for_path.
* tree-diagnostic.h (default_tree_make_json_for): Delete decl.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/diagnostic-format-json.cc | 37 ++++++++++++++++++++++++++++++++---
gcc/diagnostic.h | 2 --
gcc/tree-diagnostic-path.cc | 32 ------------------------------
gcc/tree-diagnostic.cc | 1 -
gcc/tree-diagnostic.h | 2 --
5 files changed, 34 insertions(+), 40 deletions(-)
diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc
index 0782ae831eb..2bdc2c13d37 100644
--- a/gcc/diagnostic-format-json.cc
+++ b/gcc/diagnostic-format-json.cc
@@ -25,8 +25,10 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "selftest-diagnostic.h"
#include "diagnostic-metadata.h"
+#include "diagnostic-path.h"
#include "json.h"
#include "selftest.h"
+#include "logical-location.h"
/* Subclass of diagnostic_output_format for JSON output. */
@@ -187,6 +189,36 @@ json_from_metadata (const diagnostic_metadata *metadata)
return metadata_obj;
}
+/* Make a JSON value for PATH. */
+
+static json::value *
+make_json_for_path (diagnostic_context *context,
+ const diagnostic_path *path)
+{
+ json::array *path_array = new json::array ();
+ for (unsigned i = 0; i < path->num_events (); i++)
+ {
+ const diagnostic_event &event = path->get_event (i);
+
+ json::object *event_obj = new json::object ();
+ if (event.get_location ())
+ event_obj->set ("location",
+ json_from_expanded_location (context,
+ event.get_location ()));
+ label_text event_text (event.get_desc (false));
+ event_obj->set_string ("description", event_text.get ());
+ if (const logical_location *logical_loc = event.get_logical_location ())
+ {
+ 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);
+ }
+ return path_array;
+}
+
+
/* Implementation of "on_end_diagnostic" vfunc for JSON output.
Generate a JSON object for DIAGNOSTIC, and store for output
within current diagnostic group. */
@@ -291,10 +323,9 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic,
}
const diagnostic_path *path = richloc->get_path ();
- if (path && m_context.m_make_json_for_path)
+ if (path)
{
- json::value *path_value
- = m_context.m_make_json_for_path (&m_context, path);
+ json::value *path_value = make_json_for_path (&m_context, path);
diag_obj->set ("path", path_value);
}
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 9a9571bb76d..ff2aa3dd9a3 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -713,8 +713,6 @@ private:
public:
void (*m_print_path) (diagnostic_context *, const diagnostic_path *);
- json::value *(*m_make_json_for_path) (diagnostic_context *,
- const diagnostic_path *);
/* Auxiliary data for client. */
void *m_client_aux_data;
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index 39a85d33015..40b197d971c 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-diagnostic.h"
#include "intl.h"
#include "diagnostic-path.h"
-#include "json.h"
#include "gcc-rich-location.h"
#include "diagnostic-color.h"
#include "diagnostic-event-id.h"
@@ -954,37 +953,6 @@ default_tree_diagnostic_path_printer (diagnostic_context *context,
}
}
-/* This has to be here, rather than diagnostic-format-json.cc,
- since diagnostic-format-json.o is within OBJS-libcommon and thus
- doesn't have access to trees (for m_fndecl). */
-
-json::value *
-default_tree_make_json_for_path (diagnostic_context *context,
- const diagnostic_path *path)
-{
- json::array *path_array = new json::array ();
- for (unsigned i = 0; i < path->num_events (); i++)
- {
- const diagnostic_event &event = path->get_event (i);
-
- json::object *event_obj = new json::object ();
- if (event.get_location ())
- event_obj->set ("location",
- json_from_expanded_location (context,
- event.get_location ()));
- label_text event_text (event.get_desc (false));
- event_obj->set_string ("description", event_text.get ());
- if (const logical_location *logical_loc = event.get_logical_location ())
- {
- 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);
- }
- return path_array;
-}
-
#if CHECKING_P
namespace selftest {
diff --git a/gcc/tree-diagnostic.cc b/gcc/tree-diagnostic.cc
index a660c7d0785..f6e2a73497a 100644
--- a/gcc/tree-diagnostic.cc
+++ b/gcc/tree-diagnostic.cc
@@ -375,7 +375,6 @@ tree_diagnostics_defaults (diagnostic_context *context)
diagnostic_finalizer (context) = default_diagnostic_finalizer;
diagnostic_format_decoder (context) = default_tree_printer;
context->m_print_path = default_tree_diagnostic_path_printer;
- context->m_make_json_for_path = default_tree_make_json_for_path;
context->set_set_locations_callback (set_inlining_locations);
context->set_client_data_hooks (make_compiler_data_hooks ());
}
diff --git a/gcc/tree-diagnostic.h b/gcc/tree-diagnostic.h
index 1d13368537a..7959294f489 100644
--- a/gcc/tree-diagnostic.h
+++ b/gcc/tree-diagnostic.h
@@ -59,8 +59,6 @@ bool default_tree_printer (pretty_printer *, text_info *, const char *,
extern void default_tree_diagnostic_path_printer (diagnostic_context *,
const diagnostic_path *);
-extern json::value *default_tree_make_json_for_path (diagnostic_context *,
- const diagnostic_path *);
extern void maybe_unwind_expanded_macro_loc (diagnostic_context *context,
location_t where);
--
2.26.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/7] diagnostics: introduce diagnostic-macro-unwinding.h/cc
2024-06-18 15:08 [pushed 0/7] diagnostics: remove "tree" dependency from diagnostic paths David Malcolm
` (3 preceding siblings ...)
2024-06-18 15:08 ` [PATCH 4/7] diagnostics: eliminate diagnostic_context::m_make_json_for_path David Malcolm
@ 2024-06-18 15:08 ` David Malcolm
2024-06-18 15:08 ` [PATCH 6/7] diagnostics: eliminate diagnostic_context::m_print_path callback David Malcolm
2024-06-18 15:08 ` [PATCH 7/7] diagnostics: rename tree-diagnostic-path.cc to diagnostic-path.cc David Malcolm
6 siblings, 0 replies; 9+ messages in thread
From: David Malcolm @ 2024-06-18 15:08 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
Eliminate a dependency on "tree" from the code used by
diagnostic_path handling.
No functional change intended.
gcc/ChangeLog:
* Makefile.in (OBJS): Add diagnostic-macro-unwinding.o.
gcc/c-family/ChangeLog:
* c-opts.cc: Replace include of "tree-diagnostic.h" with
"diagnostic-macro-unwinding.h".
gcc/ChangeLog:
* diagnostic-macro-unwinding.cc: New file, with material taken
from tree-diagnostic.cc.
* diagnostic-macro-unwinding.h: New file, with material taken
from tree-diagnostic.h.
* tree-diagnostic-path.cc: Repalce include of "tree-diagnostic.h"
with "diagnostic-macro-unwinding.h".
* tree-diagnostic.cc (struct loc_map_pair): Move to
diagnostic-macro-unwinding.cc.
(maybe_unwind_expanded_macro_loc): Likewise.
(virt_loc_aware_diagnostic_finalizer): Likewise.
* tree-diagnostic.h (virt_loc_aware_diagnostic_finalizer): Move
decl to diagnostic-macro-unwinding.h.
(maybe_unwind_expanded_macro_loc): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/Makefile.in | 1 +
gcc/c-family/c-opts.cc | 2 +-
gcc/diagnostic-macro-unwinding.cc | 221 ++++++++++++++++++++++++++++++
gcc/diagnostic-macro-unwinding.h | 29 ++++
gcc/tree-diagnostic-path.cc | 2 +-
gcc/tree-diagnostic.cc | 195 --------------------------
gcc/tree-diagnostic.h | 5 -
7 files changed, 253 insertions(+), 202 deletions(-)
create mode 100644 gcc/diagnostic-macro-unwinding.cc
create mode 100644 gcc/diagnostic-macro-unwinding.h
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a2799b8d826..e701d9fb082 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1826,6 +1826,7 @@ OBJS = \
OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \
diagnostic-format-json.o \
diagnostic-format-sarif.o \
+ diagnostic-macro-unwinding.o \
diagnostic-show-locus.o \
edit-context.o \
pretty-print.o intl.o \
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index faaf9ee6350..33114f13c8d 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "toplev.h"
#include "langhooks.h"
-#include "tree-diagnostic.h" /* for virt_loc_aware_diagnostic_finalizer */
+#include "diagnostic-macro-unwinding.h" /* for virt_loc_aware_diagnostic_finalizer */
#include "intl.h"
#include "cppdefault.h"
#include "incpath.h"
diff --git a/gcc/diagnostic-macro-unwinding.cc b/gcc/diagnostic-macro-unwinding.cc
new file mode 100644
index 00000000000..3056d8c8afb
--- /dev/null
+++ b/gcc/diagnostic-macro-unwinding.cc
@@ -0,0 +1,221 @@
+/* Code for unwinding macro expansions in diagnostics.
+ Copyright (C) 1999-2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "diagnostic.h"
+#include "diagnostic-macro-unwinding.h"
+#include "intl.h"
+
+/* This is a pair made of a location and the line map it originated
+ from. It's used in the maybe_unwind_expanded_macro_loc function
+ below. */
+struct loc_map_pair
+{
+ const line_map_macro *map;
+ location_t where;
+};
+
+
+/* Unwind the different macro expansions that lead to the token which
+ location is WHERE and emit diagnostics showing the resulting
+ unwound macro expansion trace. Let's look at an example to see how
+ the trace looks like. Suppose we have this piece of code,
+ artificially annotated with the line numbers to increase
+ legibility:
+
+ $ cat -n test.c
+ 1 #define OPERATE(OPRD1, OPRT, OPRD2) \
+ 2 OPRD1 OPRT OPRD2;
+ 3
+ 4 #define SHIFTL(A,B) \
+ 5 OPERATE (A,<<,B)
+ 6
+ 7 #define MULT(A) \
+ 8 SHIFTL (A,1)
+ 9
+ 10 void
+ 11 g ()
+ 12 {
+ 13 MULT (1.0);// 1.0 << 1; <-- so this is an error.
+ 14 }
+
+ Here is the diagnostic that we want the compiler to generate:
+
+ test.c: In function ‘g’:
+ test.c:5:14: error: invalid operands to binary << (have ‘double’ and ‘int’)
+ test.c:2:9: note: in definition of macro 'OPERATE'
+ test.c:8:3: note: in expansion of macro 'SHIFTL'
+ test.c:13:3: note: in expansion of macro 'MULT'
+
+ The part that goes from the third to the fifth line of this
+ diagnostic (the lines containing the 'note:' string) is called the
+ unwound macro expansion trace. That's the part generated by this
+ function. */
+
+void
+maybe_unwind_expanded_macro_loc (diagnostic_context *context,
+ location_t where)
+{
+ const struct line_map *map;
+ auto_vec<loc_map_pair> loc_vec;
+ unsigned ix;
+ loc_map_pair loc, *iter;
+
+ const location_t original_loc = where;
+
+ map = linemap_lookup (line_table, where);
+ if (!linemap_macro_expansion_map_p (map))
+ return;
+
+ /* Let's unwind the macros that got expanded and led to the token
+ which location is WHERE. We are going to store these macros into
+ LOC_VEC, so that we can later walk it at our convenience to
+ display a somewhat meaningful trace of the macro expansion
+ history to the user. Note that the first macro of the trace
+ (which is OPERATE in the example above) is going to be stored at
+ the beginning of LOC_VEC. */
+
+ do
+ {
+ loc.where = where;
+ loc.map = linemap_check_macro (map);
+
+ loc_vec.safe_push (loc);
+
+ /* WHERE is the location of a token inside the expansion of a
+ macro. MAP is the map holding the locations of that macro
+ expansion. Let's get the location of the token inside the
+ context that triggered the expansion of this macro.
+ This is basically how we go "down" in the trace of macro
+ expansions that led to WHERE. */
+ where = linemap_unwind_toward_expansion (line_table, where, &map);
+ } while (linemap_macro_expansion_map_p (map));
+
+ /* Now map is set to the map of the location in the source that
+ first triggered the macro expansion. This must be an ordinary map. */
+ const line_map_ordinary *ord_map = linemap_check_ordinary (map);
+
+ /* Walk LOC_VEC and print the macro expansion trace, unless the
+ first macro which expansion triggered this trace was expanded
+ inside a system header. */
+ int saved_location_line =
+ expand_location_to_spelling_point (original_loc).line;
+
+ if (!LINEMAP_SYSP (ord_map))
+ FOR_EACH_VEC_ELT (loc_vec, ix, iter)
+ {
+ /* Sometimes, in the unwound macro expansion trace, we want to
+ print a part of the context that shows where, in the
+ definition of the relevant macro, is the token (we are
+ looking at) used. That is the case in the introductory
+ comment of this function, where we print:
+
+ test.c:2:9: note: in definition of macro 'OPERATE'.
+
+ We print that "macro definition context" because the
+ diagnostic line (emitted by the call to
+ pp_ouput_formatted_text in diagnostic_report_diagnostic):
+
+ test.c:5:14: error: invalid operands to binary << (have ‘double’ and ‘int’)
+
+ does not point into the definition of the macro where the
+ token '<<' (that is an argument to the function-like macro
+ OPERATE) is used. So we must "display" the line of that
+ macro definition context to the user somehow.
+
+ A contrario, when the first interesting diagnostic line
+ points into the definition of the macro, we don't need to
+ display any line for that macro definition in the trace
+ anymore, otherwise it'd be redundant. */
+
+ /* Okay, now here is what we want. For each token resulting
+ from macro expansion we want to show: 1/ where in the
+ definition of the macro the token comes from; 2/ where the
+ macro got expanded. */
+
+ /* Resolve the location iter->where into the locus 1/ of the
+ comment above. */
+ location_t resolved_def_loc =
+ linemap_resolve_location (line_table, iter->where,
+ LRK_MACRO_DEFINITION_LOCATION, NULL);
+
+ /* Don't print trace for locations that are reserved or from
+ within a system header. */
+ const line_map_ordinary *m = NULL;
+ location_t l =
+ linemap_resolve_location (line_table, resolved_def_loc,
+ LRK_SPELLING_LOCATION, &m);
+ location_t l0 = l;
+ if (IS_ADHOC_LOC (l0))
+ l0 = get_location_from_adhoc_loc (line_table, l0);
+ if (l0 < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (m))
+ continue;
+
+ /* We need to print the context of the macro definition only
+ when the locus of the first displayed diagnostic (displayed
+ before this trace) was inside the definition of the
+ macro. */
+ const int resolved_def_loc_line = SOURCE_LINE (m, l0);
+ if (ix == 0 && saved_location_line != resolved_def_loc_line)
+ {
+ diagnostic_append_note (context, resolved_def_loc,
+ "in definition of macro %qs",
+ linemap_map_get_macro_name (iter->map));
+ /* At this step, as we've printed the context of the macro
+ definition, we don't want to print the context of its
+ expansion, otherwise, it'd be redundant. */
+ continue;
+ }
+
+ /* Resolve the location of the expansion point of the macro
+ which expansion gave the token represented by def_loc.
+ This is the locus 2/ of the earlier comment. */
+ location_t resolved_exp_loc =
+ linemap_resolve_location (line_table,
+ iter->map->get_expansion_point_location (),
+ LRK_MACRO_DEFINITION_LOCATION, NULL);
+
+ diagnostic_append_note (context, resolved_exp_loc,
+ "in expansion of macro %qs",
+ linemap_map_get_macro_name (iter->map));
+ }
+}
+
+/* This is a diagnostic finalizer implementation that is aware of
+ virtual locations produced by libcpp.
+
+ It has to be called by the diagnostic finalizer of front ends that
+ uses libcpp and wish to get diagnostics involving tokens resulting
+ from macro expansion.
+
+ For a given location, if said location belongs to a token
+ resulting from a macro expansion, this starter prints the context
+ of the token. E.g, for multiply nested macro expansion, it
+ unwinds the nested macro expansions and prints them in a manner
+ that is similar to what is done for function call stacks, or
+ template instantiation contexts. */
+void
+virt_loc_aware_diagnostic_finalizer (diagnostic_context *context,
+ const diagnostic_info *diagnostic)
+{
+ maybe_unwind_expanded_macro_loc (context, diagnostic_location (diagnostic));
+}
diff --git a/gcc/diagnostic-macro-unwinding.h b/gcc/diagnostic-macro-unwinding.h
new file mode 100644
index 00000000000..74083cd56de
--- /dev/null
+++ b/gcc/diagnostic-macro-unwinding.h
@@ -0,0 +1,29 @@
+/* Code for unwinding macro expansions in diagnostics.
+ Copyright (C) 2000-2024 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_DIAGNOSTIC_MACRO_UNWINDING_H
+#define GCC_DIAGNOSTIC_MACRO_UNWINDING_H
+
+void virt_loc_aware_diagnostic_finalizer (diagnostic_context *,
+ const diagnostic_info *);
+
+extern void maybe_unwind_expanded_macro_loc (diagnostic_context *context,
+ location_t where);
+
+#endif /* ! GCC_DIAGNOSTIC_MACRO_UNWINDING_H */
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index 40b197d971c..adaaf30b84f 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "diagnostic.h"
-#include "tree-diagnostic.h"
+#include "diagnostic-macro-unwinding.h"
#include "intl.h"
#include "diagnostic-path.h"
#include "gcc-rich-location.h"
diff --git a/gcc/tree-diagnostic.cc b/gcc/tree-diagnostic.cc
index f6e2a73497a..f236f3db0b2 100644
--- a/gcc/tree-diagnostic.cc
+++ b/gcc/tree-diagnostic.cc
@@ -51,201 +51,6 @@ default_tree_diagnostic_starter (diagnostic_context *context,
diagnostic));
}
-/* This is a pair made of a location and the line map it originated
- from. It's used in the maybe_unwind_expanded_macro_loc function
- below. */
-struct loc_map_pair
-{
- const line_map_macro *map;
- location_t where;
-};
-
-
-/* Unwind the different macro expansions that lead to the token which
- location is WHERE and emit diagnostics showing the resulting
- unwound macro expansion trace. Let's look at an example to see how
- the trace looks like. Suppose we have this piece of code,
- artificially annotated with the line numbers to increase
- legibility:
-
- $ cat -n test.c
- 1 #define OPERATE(OPRD1, OPRT, OPRD2) \
- 2 OPRD1 OPRT OPRD2;
- 3
- 4 #define SHIFTL(A,B) \
- 5 OPERATE (A,<<,B)
- 6
- 7 #define MULT(A) \
- 8 SHIFTL (A,1)
- 9
- 10 void
- 11 g ()
- 12 {
- 13 MULT (1.0);// 1.0 << 1; <-- so this is an error.
- 14 }
-
- Here is the diagnostic that we want the compiler to generate:
-
- test.c: In function ‘g’:
- test.c:5:14: error: invalid operands to binary << (have ‘double’ and ‘int’)
- test.c:2:9: note: in definition of macro 'OPERATE'
- test.c:8:3: note: in expansion of macro 'SHIFTL'
- test.c:13:3: note: in expansion of macro 'MULT'
-
- The part that goes from the third to the fifth line of this
- diagnostic (the lines containing the 'note:' string) is called the
- unwound macro expansion trace. That's the part generated by this
- function. */
-
-void
-maybe_unwind_expanded_macro_loc (diagnostic_context *context,
- location_t where)
-{
- const struct line_map *map;
- auto_vec<loc_map_pair> loc_vec;
- unsigned ix;
- loc_map_pair loc, *iter;
-
- const location_t original_loc = where;
-
- map = linemap_lookup (line_table, where);
- if (!linemap_macro_expansion_map_p (map))
- return;
-
- /* Let's unwind the macros that got expanded and led to the token
- which location is WHERE. We are going to store these macros into
- LOC_VEC, so that we can later walk it at our convenience to
- display a somewhat meaningful trace of the macro expansion
- history to the user. Note that the first macro of the trace
- (which is OPERATE in the example above) is going to be stored at
- the beginning of LOC_VEC. */
-
- do
- {
- loc.where = where;
- loc.map = linemap_check_macro (map);
-
- loc_vec.safe_push (loc);
-
- /* WHERE is the location of a token inside the expansion of a
- macro. MAP is the map holding the locations of that macro
- expansion. Let's get the location of the token inside the
- context that triggered the expansion of this macro.
- This is basically how we go "down" in the trace of macro
- expansions that led to WHERE. */
- where = linemap_unwind_toward_expansion (line_table, where, &map);
- } while (linemap_macro_expansion_map_p (map));
-
- /* Now map is set to the map of the location in the source that
- first triggered the macro expansion. This must be an ordinary map. */
- const line_map_ordinary *ord_map = linemap_check_ordinary (map);
-
- /* Walk LOC_VEC and print the macro expansion trace, unless the
- first macro which expansion triggered this trace was expanded
- inside a system header. */
- int saved_location_line =
- expand_location_to_spelling_point (original_loc).line;
-
- if (!LINEMAP_SYSP (ord_map))
- FOR_EACH_VEC_ELT (loc_vec, ix, iter)
- {
- /* Sometimes, in the unwound macro expansion trace, we want to
- print a part of the context that shows where, in the
- definition of the relevant macro, is the token (we are
- looking at) used. That is the case in the introductory
- comment of this function, where we print:
-
- test.c:2:9: note: in definition of macro 'OPERATE'.
-
- We print that "macro definition context" because the
- diagnostic line (emitted by the call to
- pp_ouput_formatted_text in diagnostic_report_diagnostic):
-
- test.c:5:14: error: invalid operands to binary << (have ‘double’ and ‘int’)
-
- does not point into the definition of the macro where the
- token '<<' (that is an argument to the function-like macro
- OPERATE) is used. So we must "display" the line of that
- macro definition context to the user somehow.
-
- A contrario, when the first interesting diagnostic line
- points into the definition of the macro, we don't need to
- display any line for that macro definition in the trace
- anymore, otherwise it'd be redundant. */
-
- /* Okay, now here is what we want. For each token resulting
- from macro expansion we want to show: 1/ where in the
- definition of the macro the token comes from; 2/ where the
- macro got expanded. */
-
- /* Resolve the location iter->where into the locus 1/ of the
- comment above. */
- location_t resolved_def_loc =
- linemap_resolve_location (line_table, iter->where,
- LRK_MACRO_DEFINITION_LOCATION, NULL);
-
- /* Don't print trace for locations that are reserved or from
- within a system header. */
- const line_map_ordinary *m = NULL;
- location_t l =
- linemap_resolve_location (line_table, resolved_def_loc,
- LRK_SPELLING_LOCATION, &m);
- location_t l0 = l;
- if (IS_ADHOC_LOC (l0))
- l0 = get_location_from_adhoc_loc (line_table, l0);
- if (l0 < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (m))
- continue;
-
- /* We need to print the context of the macro definition only
- when the locus of the first displayed diagnostic (displayed
- before this trace) was inside the definition of the
- macro. */
- const int resolved_def_loc_line = SOURCE_LINE (m, l0);
- if (ix == 0 && saved_location_line != resolved_def_loc_line)
- {
- diagnostic_append_note (context, resolved_def_loc,
- "in definition of macro %qs",
- linemap_map_get_macro_name (iter->map));
- /* At this step, as we've printed the context of the macro
- definition, we don't want to print the context of its
- expansion, otherwise, it'd be redundant. */
- continue;
- }
-
- /* Resolve the location of the expansion point of the macro
- which expansion gave the token represented by def_loc.
- This is the locus 2/ of the earlier comment. */
- location_t resolved_exp_loc =
- linemap_resolve_location (line_table,
- iter->map->get_expansion_point_location (),
- LRK_MACRO_DEFINITION_LOCATION, NULL);
-
- diagnostic_append_note (context, resolved_exp_loc,
- "in expansion of macro %qs",
- linemap_map_get_macro_name (iter->map));
- }
-}
-
-/* This is a diagnostic finalizer implementation that is aware of
- virtual locations produced by libcpp.
-
- It has to be called by the diagnostic finalizer of front ends that
- uses libcpp and wish to get diagnostics involving tokens resulting
- from macro expansion.
-
- For a given location, if said location belongs to a token
- resulting from a macro expansion, this starter prints the context
- of the token. E.g, for multiply nested macro expansion, it
- unwinds the nested macro expansions and prints them in a manner
- that is similar to what is done for function call stacks, or
- template instantiation contexts. */
-void
-virt_loc_aware_diagnostic_finalizer (diagnostic_context *context,
- const diagnostic_info *diagnostic)
-{
- maybe_unwind_expanded_macro_loc (context, diagnostic_location (diagnostic));
-}
-
/* Default tree printer. Handles declarations only. */
bool
default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
diff --git a/gcc/tree-diagnostic.h b/gcc/tree-diagnostic.h
index 7959294f489..648d6e6ab91 100644
--- a/gcc/tree-diagnostic.h
+++ b/gcc/tree-diagnostic.h
@@ -50,8 +50,6 @@ along with GCC; see the file COPYING3. If not see
void diagnostic_report_current_function (diagnostic_context *,
const diagnostic_info *);
-void virt_loc_aware_diagnostic_finalizer (diagnostic_context *,
- const diagnostic_info *);
void tree_diagnostics_defaults (diagnostic_context *context);
bool default_tree_printer (pretty_printer *, text_info *, const char *,
@@ -60,7 +58,4 @@ bool default_tree_printer (pretty_printer *, text_info *, const char *,
extern void default_tree_diagnostic_path_printer (diagnostic_context *,
const diagnostic_path *);
-extern void maybe_unwind_expanded_macro_loc (diagnostic_context *context,
- location_t where);
-
#endif /* ! GCC_TREE_DIAGNOSTIC_H */
--
2.26.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 6/7] diagnostics: eliminate diagnostic_context::m_print_path callback
2024-06-18 15:08 [pushed 0/7] diagnostics: remove "tree" dependency from diagnostic paths David Malcolm
` (4 preceding siblings ...)
2024-06-18 15:08 ` [PATCH 5/7] diagnostics: introduce diagnostic-macro-unwinding.h/cc David Malcolm
@ 2024-06-18 15:08 ` David Malcolm
2024-06-18 18:22 ` David Malcolm
2024-06-18 15:08 ` [PATCH 7/7] diagnostics: rename tree-diagnostic-path.cc to diagnostic-path.cc David Malcolm
6 siblings, 1 reply; 9+ messages in thread
From: David Malcolm @ 2024-06-18 15:08 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
No functional change intended.
gcc/ChangeLog:
* diagnostic-format-json.cc (diagnostic_output_format_init_json):
Replace clearing of diagnostic_context::m_print_path callback with
setting the path format to DPF_NONE.
* diagnostic-format-sarif.cc
(diagnostic_output_format_init_sarif): Likewise.
* diagnostic.cc (diagnostic_context::show_any_path): Replace call
to diagnostic_context::m_print_path callback with a direct call to
diagnostic_context::print_path.
* diagnostic.h (diagnostic_context::print_path): New decl.
(diagnostic_context::m_print_path): Delete callback.
* tree-diagnostic-path.cc (default_tree_diagnostic_path_printer):
Convert to...
(diagnostic_context::print_path): ...this.
* tree-diagnostic.cc (tree_diagnostics_defaults): Delete
initialization of m_print_path.
* tree-diagnostic.h (default_tree_diagnostic_path_printer): Delete
decl.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/diagnostic-format-json.cc | 4 ++--
gcc/diagnostic-format-sarif.cc | 4 +++-
gcc/diagnostic.cc | 3 +--
gcc/diagnostic.h | 4 ++--
gcc/tree-diagnostic-path.cc | 23 +++++++++++------------
gcc/tree-diagnostic.cc | 1 -
gcc/tree-diagnostic.h | 3 ---
7 files changed, 19 insertions(+), 23 deletions(-)
diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc
index 2bdc2c13d37..ec03ac15aeb 100644
--- a/gcc/diagnostic-format-json.cc
+++ b/gcc/diagnostic-format-json.cc
@@ -395,8 +395,8 @@ private:
static void
diagnostic_output_format_init_json (diagnostic_context *context)
{
- /* Override callbacks. */
- context->m_print_path = nullptr; /* handled in json_end_diagnostic. */
+ /* Suppress normal textual path output. */
+ context->set_path_format (DPF_NONE);
/* The metadata is handled in JSON format, rather than as text. */
context->set_show_cwe (false);
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index 79116f051bc..5f438dd38a8 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -1991,8 +1991,10 @@ private:
static void
diagnostic_output_format_init_sarif (diagnostic_context *context)
{
+ /* Suppress normal textual path output. */
+ context->set_path_format (DPF_NONE);
+
/* Override callbacks. */
- context->m_print_path = nullptr; /* handled in sarif_end_diagnostic. */
context->set_ice_handler_callback (sarif_ice_handler);
/* The metadata is handled in SARIF format, rather than as text. */
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 844eb8e1048..471135f16de 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -915,8 +915,7 @@ diagnostic_context::show_any_path (const diagnostic_info &diagnostic)
if (!path)
return;
- if (m_print_path)
- m_print_path (this, path);
+ print_path (path);
}
/* class diagnostic_event. */
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index ff2aa3dd9a3..c6846525da3 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -583,6 +583,8 @@ private:
pretty_printer *pp,
diagnostic_source_effect_info *effect_info);
+ void print_path (const diagnostic_path *path);
+
/* Data members.
Ideally, all of these would be private and have "m_" prefixes. */
@@ -712,8 +714,6 @@ private:
urlifier *m_urlifier;
public:
- void (*m_print_path) (diagnostic_context *, const diagnostic_path *);
-
/* Auxiliary data for client. */
void *m_client_aux_data;
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index adaaf30b84f..35f8ea2b8b6 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -884,17 +884,16 @@ print_path_summary_as_text (const path_summary *ps, diagnostic_context *dc,
} /* end of anonymous namespace for path-printing code. */
-/* Print PATH to CONTEXT, according to CONTEXT's path_format. */
+/* Print PATH according to this context's path_format. */
void
-default_tree_diagnostic_path_printer (diagnostic_context *context,
- const diagnostic_path *path)
+diagnostic_context::print_path (const diagnostic_path *path)
{
gcc_assert (path);
const unsigned num_events = path->num_events ();
- switch (context->get_path_format ())
+ switch (get_path_format ())
{
case DPF_NONE:
/* Do nothing. */
@@ -909,7 +908,7 @@ default_tree_diagnostic_path_printer (diagnostic_context *context,
label_text event_text (event.get_desc (false));
gcc_assert (event_text.get ());
diagnostic_event_id_t event_id (i);
- if (context->show_path_depths_p ())
+ if (this->show_path_depths_p ())
{
int stack_depth = event.get_stack_depth ();
/* -fdiagnostics-path-format=separate-events doesn't print
@@ -941,13 +940,13 @@ default_tree_diagnostic_path_printer (diagnostic_context *context,
{
/* Consolidate related events. */
path_summary summary (*path, true,
- context->m_source_printing.show_event_links_p);
- char *saved_prefix = pp_take_prefix (context->printer);
- pp_set_prefix (context->printer, NULL);
- print_path_summary_as_text (&summary, context,
- context->show_path_depths_p ());
- pp_flush (context->printer);
- pp_set_prefix (context->printer, saved_prefix);
+ m_source_printing.show_event_links_p);
+ char *saved_prefix = pp_take_prefix (this->printer);
+ pp_set_prefix (this->printer, NULL);
+ print_path_summary_as_text (&summary, this,
+ show_path_depths_p ());
+ pp_flush (this->printer);
+ pp_set_prefix (this->printer, saved_prefix);
}
break;
}
diff --git a/gcc/tree-diagnostic.cc b/gcc/tree-diagnostic.cc
index f236f3db0b2..fc78231dfa4 100644
--- a/gcc/tree-diagnostic.cc
+++ b/gcc/tree-diagnostic.cc
@@ -179,7 +179,6 @@ tree_diagnostics_defaults (diagnostic_context *context)
diagnostic_starter (context) = default_tree_diagnostic_starter;
diagnostic_finalizer (context) = default_diagnostic_finalizer;
diagnostic_format_decoder (context) = default_tree_printer;
- context->m_print_path = default_tree_diagnostic_path_printer;
context->set_set_locations_callback (set_inlining_locations);
context->set_client_data_hooks (make_compiler_data_hooks ());
}
diff --git a/gcc/tree-diagnostic.h b/gcc/tree-diagnostic.h
index 648d6e6ab91..6ebac381ace 100644
--- a/gcc/tree-diagnostic.h
+++ b/gcc/tree-diagnostic.h
@@ -55,7 +55,4 @@ void tree_diagnostics_defaults (diagnostic_context *context);
bool default_tree_printer (pretty_printer *, text_info *, const char *,
int, bool, bool, bool, bool *, const char **);
-extern void default_tree_diagnostic_path_printer (diagnostic_context *,
- const diagnostic_path *);
-
#endif /* ! GCC_TREE_DIAGNOSTIC_H */
--
2.26.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 6/7] diagnostics: eliminate diagnostic_context::m_print_path callback
2024-06-18 15:08 ` [PATCH 6/7] diagnostics: eliminate diagnostic_context::m_print_path callback David Malcolm
@ 2024-06-18 18:22 ` David Malcolm
0 siblings, 0 replies; 9+ messages in thread
From: David Malcolm @ 2024-06-18 18:22 UTC (permalink / raw)
To: gcc-patches
On Tue, 2024-06-18 at 11:08 -0400, David Malcolm wrote:
> No functional change intended.
Sorry, it looks like I should have combined patches 6 and 7, in that
patch 6 temporarily breaks the build:
e.g.:
https://builder.sourceware.org/buildbot/#/builders/156/builds/10063
make[2]: Leaving directory '/home/mjw/wildebeest/buildbot/gcc-fedora-ppc64le/gcc-build/gcc'
g++ -no-pie -g -O2 -DIN_GCC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Wconditionally-supported -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -DHAVE_CONFIG_H -no-pie gcov-dump.o \
hash-table.o ggc-none.o\
libcommon.a ../libcpp/libcpp.a ../libbacktrace/.libs/libbacktrace.a ../libiberty/libiberty.a ../libdecnumber/libdecnumber.a -o gcov-dump
/usr/bin/ld: libcommon.a(diagnostic.o): in function `diagnostic_context::show_any_path(diagnostic_info const&)':
/home/mjw/wildebeest/buildbot/gcc-fedora-ppc64le/gcc-build/gcc/../../gcc/gcc/diagnostic.cc:918:(.text+0x2084): undefined reference to `diagnostic_context::print_path(diagnostic_path const*)'
/usr/bin/ld: /home/mjw/wildebeest/buildbot/gcc-fedora-ppc64le/gcc-build/gcc/../../gcc/gcc/diagnostic.cc:918:(.text+0x4a34): undefined reference to `diagnostic_context::print_path(diagnostic_path const*)'
collect2: error: ld returned 1 exit status
Should be fixed by patch 7 in the kit, which puts that symbol in
libcommon.a; am continuing to watch the post-commit CI.
Sorry again
Dave
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 7/7] diagnostics: rename tree-diagnostic-path.cc to diagnostic-path.cc
2024-06-18 15:08 [pushed 0/7] diagnostics: remove "tree" dependency from diagnostic paths David Malcolm
` (5 preceding siblings ...)
2024-06-18 15:08 ` [PATCH 6/7] diagnostics: eliminate diagnostic_context::m_print_path callback David Malcolm
@ 2024-06-18 15:08 ` David Malcolm
6 siblings, 0 replies; 9+ messages in thread
From: David Malcolm @ 2024-06-18 15:08 UTC (permalink / raw)
To: gcc-patches; +Cc: David Malcolm
Now that nothing in tree-diagnostic-path.cc uses "tree", this patch
renames it to diagnostic-path.cc and moves it from OBJS to
OBJS-libcommon.
No functional change intended.
gcc/ChangeLog:
* Makefile.in (OBJS): Move selftest-diagnostic-path.o,
selftest-logical-location.o, and tree-diagnostic-path.o to...
(OBJS-libcommon): ...here, renaming tree-diagnostic-path.o to
diagnostic-path.o.
* tree-diagnostic-path.cc: Rename to...
* diagnostic-path.cc: ...this. Drop include of "tree.h".
(tree_diagnostic_path_cc_tests): Rename to...
(diagnostic_path_cc_tests): ...this.
* selftest-run-tests.cc (selftest::run_tests): Update for above
renaming.
* selftest.h (tree_diagnostic_path_cc_tests): Rename decl to...
(diagnostic_path_cc_tests): ...this.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/Makefile.in | 6 +++---
gcc/{tree-diagnostic-path.cc => diagnostic-path.cc} | 3 +--
gcc/selftest-run-tests.cc | 2 +-
gcc/selftest.h | 2 +-
4 files changed, 6 insertions(+), 7 deletions(-)
rename gcc/{tree-diagnostic-path.cc => diagnostic-path.cc} (99%)
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index e701d9fb082..638ea6b2307 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1700,8 +1700,6 @@ OBJS = \
ubsan.o \
sanopt.o \
sancov.o \
- selftest-diagnostic-path.o \
- selftest-logical-location.o \
simple-diagnostic-path.o \
tree-call-cdce.o \
tree-cfg.o \
@@ -1712,7 +1710,6 @@ OBJS = \
tree-dfa.o \
tree-diagnostic.o \
tree-diagnostic-client-data-hooks.o \
- tree-diagnostic-path.o \
tree-dump.o \
tree-eh.o \
tree-emutls.o \
@@ -1827,6 +1824,7 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \
diagnostic-format-json.o \
diagnostic-format-sarif.o \
diagnostic-macro-unwinding.o \
+ diagnostic-path.o \
diagnostic-show-locus.o \
edit-context.o \
pretty-print.o intl.o \
@@ -1834,6 +1832,8 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \
sbitmap.o \
vec.o input.o hash-table.o ggc-none.o memory-block.o \
selftest.o selftest-diagnostic.o sort.o \
+ selftest-diagnostic-path.o \
+ selftest-logical-location.o \
text-art/box-drawing.o \
text-art/canvas.o \
text-art/ruler.o \
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/diagnostic-path.cc
similarity index 99%
rename from gcc/tree-diagnostic-path.cc
rename to gcc/diagnostic-path.cc
index 35f8ea2b8b6..882dc1c5805 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/diagnostic-path.cc
@@ -25,7 +25,6 @@ along with GCC; see the file COPYING3. If not see
#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
-#include "tree.h"
#include "diagnostic.h"
#include "diagnostic-macro-unwinding.h"
#include "intl.h"
@@ -2199,7 +2198,7 @@ control_flow_tests (const line_table_case &case_)
/* Run all of the selftests within this file. */
void
-tree_diagnostic_path_cc_tests ()
+diagnostic_path_cc_tests ()
{
/* In a few places we use the global dc's printer to determine
colorization so ensure this off during the tests. */
diff --git a/gcc/selftest-run-tests.cc b/gcc/selftest-run-tests.cc
index 3275db38ba9..e6779206c47 100644
--- a/gcc/selftest-run-tests.cc
+++ b/gcc/selftest-run-tests.cc
@@ -102,7 +102,7 @@ selftest::run_tests ()
spellcheck_cc_tests ();
spellcheck_tree_cc_tests ();
tree_cfg_cc_tests ();
- tree_diagnostic_path_cc_tests ();
+ diagnostic_path_cc_tests ();
simple_diagnostic_path_cc_tests ();
attribs_cc_tests ();
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 2d1aa91607e..dcb1463ed90 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -222,6 +222,7 @@ extern void cgraph_cc_tests ();
extern void convert_cc_tests ();
extern void diagnostic_color_cc_tests ();
extern void diagnostic_format_json_cc_tests ();
+extern void diagnostic_path_cc_tests ();
extern void diagnostic_show_locus_cc_tests ();
extern void digraph_cc_tests ();
extern void dumpfile_cc_tests ();
@@ -259,7 +260,6 @@ extern void sreal_cc_tests ();
extern void store_merging_cc_tests ();
extern void tree_cc_tests ();
extern void tree_cfg_cc_tests ();
-extern void tree_diagnostic_path_cc_tests ();
extern void tristate_cc_tests ();
extern void typed_splay_tree_cc_tests ();
extern void vec_cc_tests ();
--
2.26.3
^ permalink raw reply [flat|nested] 9+ messages in thread