This patch eliminates the PLUGIN_ANALYZER_INIT event in favor of a new
analyzer_events_channel that can be subscribed to, and ports all the
in-tree analyzer plugins to using it.
The PLUGIN_* approach isn't typesafe, and the name suggests it's only
meant to be used for plugins, whereas the pub/sub approach is typesafe,
and treats the publish/subscribe network as orthogonal to whether the
code is built into the executable or is a plugin.
gcc/analyzer/ChangeLog:
* common.h: Define INCLUDE_LIST.
(class plugin_analyzer_init_iface): Replace with...
(gcc::topics::analyzer_events::on_ana_init): ...this.
(gcc::topics::analyzer_events::subscriber): New.
* engine.cc: Include "context.h" and "channels.h".
(class plugin_analyzer_init_impl): Replace with...
(class impl_on_ana_init): ...this. Fix some overlong lines.
(impl_run_checkers): Port from PLUGIN_ANALYZER_INIT to using
publish/subscribe framework.
gcc/ChangeLog:
* channels.h (gcc::topics::analyzer_events::subscriber): New
forward decl.
(compiler_channels::analyzer_events_channel): New field.
* doc/plugins.texi (PLUGIN_ANALYZER_INIT): Delete.
* plugin.cc (register_callback): Delete PLUGIN_ANALYZER_INIT.
(invoke_plugin_callbacks_full): Likewise.
* plugin.def (PLUGIN_ANALYZER_INIT): Delete this event.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/analyzer_cpython_plugin.cc: Port from
PLUGIN_ANALYZER_INIT to subscribing to analyzer_events_channel.
* gcc.dg/plugin/analyzer_gil_plugin.cc: Likewise.
* gcc.dg/plugin/analyzer_kernel_plugin.cc: Likewise.
* gcc.dg/plugin/analyzer_known_fns_plugin.cc: Likewise.
Signed-off-by: David Malcolm <[email protected]>
---
gcc/analyzer/common.h | 47 ++++++++++++----
gcc/analyzer/engine.cc | 36 ++++++++-----
gcc/channels.h | 2 +
gcc/doc/plugins.texi | 4 --
gcc/plugin.cc | 2 -
gcc/plugin.def | 4 --
.../gcc.dg/plugin/analyzer_cpython_plugin.cc | 53 ++++++++++---------
.../gcc.dg/plugin/analyzer_gil_plugin.cc | 30 +++++------
.../gcc.dg/plugin/analyzer_kernel_plugin.cc | 43 ++++++++-------
.../plugin/analyzer_known_fns_plugin.cc | 37 +++++++------
10 files changed, 142 insertions(+), 116 deletions(-)
diff --git a/gcc/analyzer/common.h b/gcc/analyzer/common.h
index ac3048c796e3d..a30dbc1e6bcc0 100644
--- a/gcc/analyzer/common.h
+++ b/gcc/analyzer/common.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_ANALYZER_COMMON_H
#include "config.h"
+#define INCLUDE_LIST
#define INCLUDE_MAP
#define INCLUDE_STRING
#define INCLUDE_VECTOR
@@ -354,17 +355,6 @@ extern void register_known_file_functions
(known_function_manager &kfm);
extern void register_known_functions_lang_cp (known_function_manager &kfm);
extern void register_varargs_builtins (known_function_manager &kfm);
-/* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks. */
-
-class plugin_analyzer_init_iface
-{
-public:
- virtual void register_state_machine (std::unique_ptr<state_machine>) = 0;
- virtual void register_known_function (const char *name,
- std::unique_ptr<known_function>) = 0;
- virtual logger *get_logger () const = 0;
-};
-
/* An enum for describing the direction of an access to memory. */
enum class access_direction
@@ -598,6 +588,41 @@ private:
#pragma GCC diagnostic ignored "-Wformat-diag"
#endif
+namespace gcc {
+namespace topics {
+
+/* A topic for messages relating to the analyzer. */
+
+namespace analyzer_events {
+
+/* A message published by the analyzer as it starts up, intended for
+ subsystems/plugins that want to register additional functionality
+ within the analyzer. */
+
+struct on_ana_init
+{
+ virtual void
+ register_state_machine (std::unique_ptr<ana::state_machine>) const = 0;
+
+ virtual void
+ register_known_function (const char *name,
+ std::unique_ptr<ana::known_function>) const = 0;
+
+ virtual ana::logger *
+ get_logger () const = 0;
+};
+
+struct subscriber {
+
+ virtual ~subscriber () = default;
+
+ virtual void on_message (const on_ana_init &) = 0;
+};
+
+} // namespace gcc::topics::analyzer_events
+} // namespace gcc::topics
+} // namespace gcc
+
#if !ENABLE_ANALYZER
extern void sorry_no_analyzer ();
#endif /* #if !ENABLE_ANALYZER */
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 9d22950d79b14..0a560462acce3 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -34,6 +34,8 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "attribs.h"
#include "tree-dfa.h"
+#include "context.h"
+#include "channels.h"
#include "text-art/dump.h"
@@ -6479,34 +6481,39 @@ dump_analyzer_json (const supergraph &sg,
free (filename);
}
-/* Concrete subclass of plugin_analyzer_init_iface, allowing plugins
- to register new state machines. */
+/* Concrete subclass of on_ana_init, allowing plugins to register
+ new state machines. */
-class plugin_analyzer_init_impl : public plugin_analyzer_init_iface
+class impl_on_ana_init : public gcc::topics::analyzer_events::on_ana_init
{
public:
- plugin_analyzer_init_impl (std::vector<std::unique_ptr<state_machine>>
&checkers,
- known_function_manager &known_fn_mgr,
- logger *logger)
+ impl_on_ana_init (std::vector<std::unique_ptr<state_machine>> &checkers,
+ known_function_manager &known_fn_mgr,
+ logger *logger)
: m_checkers (checkers),
m_known_fn_mgr (known_fn_mgr),
m_logger (logger)
{}
- void register_state_machine (std::unique_ptr<state_machine> sm) final
override
+ void
+ register_state_machine (std::unique_ptr<state_machine> sm)
+ const final override
{
LOG_SCOPE (m_logger);
m_checkers.push_back (std::move (sm));
}
- void register_known_function (const char *name,
- std::unique_ptr<known_function> kf) final
override
+ void
+ register_known_function (const char *name,
+ std::unique_ptr<known_function> kf)
+ const final override
{
LOG_SCOPE (m_logger);
m_known_fn_mgr.add (name, std::move (kf));
}
- logger *get_logger () const final override
+ logger *
+ get_logger () const final override
{
return m_logger;
}
@@ -6572,10 +6579,11 @@ impl_run_checkers (logger *logger)
register_known_functions (*eng.get_known_function_manager (),
*eng.get_model_manager ());
- plugin_analyzer_init_impl data (checkers,
- *eng.get_known_function_manager (),
- logger);
- invoke_plugin_callbacks (PLUGIN_ANALYZER_INIT, &data);
+ if (auto channel
+ = g->get_channels ().analyzer_events_channel.get_if_active ())
+ channel->publish (impl_on_ana_init (checkers,
+ *eng.get_known_function_manager (),
+ logger));
if (logger)
{
diff --git a/gcc/channels.h b/gcc/channels.h
index 433a1e7fcf62a..f03aa259037ae 100644
--- a/gcc/channels.h
+++ b/gcc/channels.h
@@ -28,6 +28,7 @@ namespace gcc {
/* Forward decls of subscribers for the various topics we have
publish/subscribe channels for. */
namespace topics {
+ namespace analyzer_events { struct subscriber; }
namespace pass_events { struct subscriber; }
} // namespace gcc::topics
@@ -35,6 +36,7 @@ namespace topics {
struct compiler_channels
{
+ pub_sub::channel<topics::analyzer_events::subscriber>
analyzer_events_channel;
pub_sub::channel<topics::pass_events::subscriber> pass_events_channel;
};
diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi
index c11167a34ef87..a909686154ef7 100644
--- a/gcc/doc/plugins.texi
+++ b/gcc/doc/plugins.texi
@@ -218,10 +218,6 @@ enum plugin_event
as a const char* pointer. */
PLUGIN_INCLUDE_FILE,
- /* Called when -fanalyzer starts. The event data is an
- ana::plugin_analyzer_init_iface *. */
- PLUGIN_ANALYZER_INIT,
-
PLUGIN_EVENT_FIRST_DYNAMIC /* Dummy event used for indexing callback
array. */
@};
diff --git a/gcc/plugin.cc b/gcc/plugin.cc
index 0de2cc2dd2c2d..d5150341b1498 100644
--- a/gcc/plugin.cc
+++ b/gcc/plugin.cc
@@ -499,7 +499,6 @@ register_callback (const char *plugin_name,
case PLUGIN_EARLY_GIMPLE_PASSES_END:
case PLUGIN_NEW_PASS:
case PLUGIN_INCLUDE_FILE:
- case PLUGIN_ANALYZER_INIT:
{
struct callback_info *new_callback;
if (!callback)
@@ -580,7 +579,6 @@ invoke_plugin_callbacks_full (int event, void *gcc_data)
case PLUGIN_EARLY_GIMPLE_PASSES_END:
case PLUGIN_NEW_PASS:
case PLUGIN_INCLUDE_FILE:
- case PLUGIN_ANALYZER_INIT:
{
/* Iterate over every callback registered with this event and
call it. */
diff --git a/gcc/plugin.def b/gcc/plugin.def
index 94e012a1e0064..2cdea1f75d9cc 100644
--- a/gcc/plugin.def
+++ b/gcc/plugin.def
@@ -99,10 +99,6 @@ DEFEVENT (PLUGIN_NEW_PASS)
as a const char* pointer. */
DEFEVENT (PLUGIN_INCLUDE_FILE)
-/* Called when -fanalyzer starts. The event data is an
- ana::plugin_analyzer_init_iface *. */
-DEFEVENT (PLUGIN_ANALYZER_INIT)
-
/* When adding a new hard-coded plugin event, don't forget to edit in
file plugin.cc the functions register_callback and
invoke_plugin_callbacks_full accordingly! */
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
index c80b2dae66bab..d0950a85a3819 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc
@@ -35,6 +35,8 @@
#include "digraph.h"
#include "analyzer/supergraph.h"
#include "sbitmap.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
@@ -1268,33 +1270,36 @@ sorry_no_cpython_plugin ()
"Python/C API", "#include <Python.h>");
}
-static void
-cpython_analyzer_init_cb (void *gcc_data, void * /*user_data */)
+namespace analyzer_events = ::gcc::topics::analyzer_events;
+
+class cpython_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: cpython_analyzer_init_cb");
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
- init_py_structs ();
+ init_py_structs ();
- if (pyobj_record == NULL_TREE)
- {
- sorry_no_cpython_plugin ();
- return;
- }
+ if (pyobj_record == NULL_TREE)
+ {
+ sorry_no_cpython_plugin ();
+ return;
+ }
- iface->register_known_function ("PyList_Append",
- std::make_unique<kf_PyList_Append> ());
- iface->register_known_function ("PyList_New",
std::make_unique<kf_PyList_New> ());
- iface->register_known_function ("PyLong_FromLong",
- std::make_unique<kf_PyLong_FromLong> ());
+ m.register_known_function ("PyList_Append",
+ std::make_unique<kf_PyList_Append> ());
+ m.register_known_function ("PyList_New",
+ std::make_unique<kf_PyList_New> ());
+ m.register_known_function ("PyLong_FromLong",
+ std::make_unique<kf_PyLong_FromLong> ());
+ m.register_known_function
+ ("__analyzer_cpython_dump_refcounts",
+ std::make_unique<kf_analyzer_cpython_dump_refcounts> ());
+ }
+} cpython_sub;
- iface->register_known_function (
- "__analyzer_cpython_dump_refcounts",
- std::make_unique<kf_analyzer_cpython_dump_refcounts> ());
-}
} // namespace ana
#endif /* #if ENABLE_ANALYZER */
@@ -1310,9 +1315,7 @@ plugin_init (struct plugin_name_args *plugin_info,
register_finish_translation_unit_callback (&stash_named_types);
register_finish_translation_unit_callback (&stash_global_vars);
region_model::register_pop_frame_callback(pyobj_refcnt_checker);
- register_callback (plugin_info->base_name, PLUGIN_ANALYZER_INIT,
- ana::cpython_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber (ana::cpython_sub);
#else
sorry_no_analyzer ();
#endif
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
index c101c45b541af..563da2f3a933c 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.cc
@@ -4,6 +4,7 @@
*/
/* { dg-options "-g" } */
+#define INCLUDE_LIST
#define INCLUDE_MEMORY
#define INCLUDE_STRING
#define INCLUDE_VECTOR
@@ -17,6 +18,8 @@
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "diagnostics/event-id.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/common.h"
#include "analyzer/analyzer-logging.h"
#include "json.h"
@@ -417,19 +420,19 @@ gil_state_machine::check_for_pyobject_usage_without_gil
(sm_context &sm_ctxt,
}
}
-/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+namespace analyzer_events = ::gcc::topics::analyzer_events;
-static void
-gil_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+class gil_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: gil_analyzer_init_cb");
- iface->register_state_machine
- (std::make_unique<gil_state_machine> (iface->get_logger ()));
-}
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
+ m.register_state_machine
+ (std::make_unique<gil_state_machine> (m.get_logger ()));
+ }
+} gil_sub;
} // namespace ana
@@ -443,10 +446,7 @@ plugin_init (struct plugin_name_args *plugin_info,
const char *plugin_name = plugin_info->base_name;
if (0)
inform (input_location, "got here; %qs", plugin_name);
- register_callback (plugin_info->base_name,
- PLUGIN_ANALYZER_INIT,
- ana::gil_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber (ana::gil_sub);
#else
sorry_no_analyzer ();
#endif
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
index 5918bd159f86f..57d55e7a75d14 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_kernel_plugin.cc
@@ -34,6 +34,8 @@
#include "digraph.h"
#include "analyzer/supergraph.h"
#include "sbitmap.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
@@ -221,26 +223,26 @@ class known_function___check_object_size : public
known_function
}
};
-/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+namespace analyzer_events = ::gcc::topics::analyzer_events;
-static void
-kernel_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+class kernel_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: kernel_analyzer_init_cb");
- iface->register_known_function
- ("copy_from_user",
- std::make_unique<known_function_copy_from_user> ());
- iface->register_known_function
- ("copy_to_user",
- std::make_unique<known_function_copy_to_user> ());
- iface->register_known_function
- ("__check_object_size",
- std::make_unique<known_function___check_object_size> ());
-}
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
+ m.register_known_function
+ ("copy_from_user",
+ std::make_unique<known_function_copy_from_user> ());
+ m.register_known_function
+ ("copy_to_user",
+ std::make_unique<known_function_copy_to_user> ());
+ m.register_known_function
+ ("__check_object_size",
+ std::make_unique<known_function___check_object_size> ());
+ }
+} kernel_sub;
} // namespace ana
@@ -254,10 +256,7 @@ plugin_init (struct plugin_name_args *plugin_info,
const char *plugin_name = plugin_info->base_name;
if (0)
inform (input_location, "got here; %qs", plugin_name);
- register_callback (plugin_info->base_name,
- PLUGIN_ANALYZER_INIT,
- ana::kernel_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber (ana::kernel_sub);
#else
sorry_no_analyzer ();
#endif
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc
b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc
index d61b69942cdb6..7080fe3b984bb 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_known_fns_plugin.cc
@@ -34,6 +34,8 @@
#include "digraph.h"
#include "analyzer/supergraph.h"
#include "sbitmap.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
@@ -174,23 +176,23 @@ public:
}
};
-/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+namespace analyzer_events = ::gcc::topics::analyzer_events;
-static void
-known_fn_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+class known_fn_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: known_fn_analyzer_init_cb");
- iface->register_known_function
- ("returns_42",
- std::make_unique<known_function_returns_42> ());
- iface->register_known_function
- ("attempt_to_copy",
- std::make_unique<known_function_attempt_to_copy> ());
-}
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
+ m.register_known_function
+ ("returns_42",
+ std::make_unique<known_function_returns_42> ());
+ m.register_known_function
+ ("attempt_to_copy",
+ std::make_unique<known_function_attempt_to_copy> ());
+ }
+} known_fn_sub;
} // namespace ana
@@ -204,10 +206,7 @@ plugin_init (struct plugin_name_args *plugin_info,
const char *plugin_name = plugin_info->base_name;
if (0)
inform (input_location, "got here; %qs", plugin_name);
- register_callback (plugin_info->base_name,
- PLUGIN_ANALYZER_INIT,
- ana::known_fn_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber
(ana::known_fn_sub);
#else
sorry_no_analyzer ();
#endif
--
2.26.3