https://gcc.gnu.org/g:bc668cf6c94a2607f280fa2447095e5f7cb81c2e
commit r16-6668-gbc668cf6c94a2607f280fa2447095e5f7cb81c2e Author: David Malcolm <[email protected]> Date: Fri Jan 9 15:54:16 2026 -0500 analyzer: port pop_frame_callbacks to pub/sub More simplification/consolidation of some callback logic in analyzer in favor of using the analyzer pub/sub channel. No functional change intended. gcc/analyzer/ChangeLog: * common.h (struct on_frame_popped): New. (subscriber::on_message): New vfunc for on_frame_popped. * region-model.cc: Include "context.h" and "channels.h". (region_model::pop_frame_callbacks): Delete. (region_model::pop_frame): Port from notify_on_pop_frame to using pub/sub channel. * region-model.h (pop_frame_callback): Delete typedef. (region_model::register_pop_frame_callback): Delete. (region_model::pop_frame_callbacks): Delete. gcc/testsuite/ChangeLog: * gcc.dg/plugin/analyzer_cpython_plugin.cc (cpython_analyzer_events_subscriber::on_message): Implement for on_frame_popped. (plugin_init): Drop call to region_model::register_pop_frame_callback in favor of the above pub/sub handler. Signed-off-by: David Malcolm <[email protected]> Diff: --- gcc/analyzer/common.h | 12 ++++++++++++ gcc/analyzer/region-model.cc | 12 +++++++++--- gcc/analyzer/region-model.h | 22 ---------------------- .../gcc.dg/plugin/analyzer_cpython_plugin.cc | 10 +++++++++- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/gcc/analyzer/common.h b/gcc/analyzer/common.h index d66c1a86e613..27ca49ee1c81 100644 --- a/gcc/analyzer/common.h +++ b/gcc/analyzer/common.h @@ -638,12 +638,24 @@ struct on_ana_init get_logger () const = 0; }; +/* A message published by the analyzer when it simulates popping a stack + frame. */ + +struct on_frame_popped +{ + const ana::region_model *m_new_model; + const ana::region_model *m_old_model; + const ana::svalue *m_retval; + ana::region_model_context *m_ctxt; +}; + struct subscriber { virtual ~subscriber () = default; virtual void on_message (const on_tu_finished &) {} virtual void on_message (const on_ana_init &) {} + virtual void on_message (const on_frame_popped &) {} }; } // namespace gcc::topics::analyzer_events diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 573680500e8a..be7b3d7b95c0 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -44,6 +44,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "fold-const.h" #include "selftest-tree.h" +#include "context.h" +#include "channels.h" #include "text-art/tree-widget.h" @@ -70,8 +72,6 @@ along with GCC; see the file COPYING3. If not see namespace ana { -auto_vec<pop_frame_callback> region_model::pop_frame_callbacks; - /* Dump T to PP in language-independent form, for debugging/logging/dumping purposes. */ @@ -6501,7 +6501,13 @@ region_model::pop_frame (tree result_lvalue, } unbind_region_and_descendents (frame_reg,poison_kind::popped_stack); - notify_on_pop_frame (this, &pre_popped_model, retval, ctxt); + + if (auto chan = g->get_channels ().analyzer_events_channel.get_if_active ()) + { + gcc::topics::analyzer_events::on_frame_popped msg + {this, &pre_popped_model, retval, ctxt}; + chan->publish (msg); + } } /* Get the number of frames in this region_model's stack. */ diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index df0c128a764e..6e9129a6dca1 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -246,11 +246,6 @@ public: struct append_regions_cb_data; -typedef void (*pop_frame_callback) (const region_model *model, - const region_model *prev_model, - const svalue *retval, - region_model_context *ctxt); - /* Roughly equivalent to a struct __cxa_exception, except we store a std::vector rather than a linked list. */ @@ -591,22 +586,6 @@ class region_model get_builtin_kf (const gcall &call, region_model_context *ctxt = nullptr) const; - static void - register_pop_frame_callback (const pop_frame_callback &callback) - { - pop_frame_callbacks.safe_push (callback); - } - - static void - notify_on_pop_frame (const region_model *model, - const region_model *prev_model, - const svalue *retval, - region_model_context *ctxt) - { - for (auto &callback : pop_frame_callbacks) - callback (model, prev_model, retval, ctxt); - } - bool called_from_main_p () const; void push_thrown_exception (const exception_node &node) @@ -736,7 +715,6 @@ private: tree fndecl, region_model_context *ctxt); - static auto_vec<pop_frame_callback> pop_frame_callbacks; /* Storing this here to avoid passing it around everywhere. */ region_model_manager *const m_mgr; diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc index fc677c5ec541..cde45c438763 100644 --- a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc +++ b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.cc @@ -1216,6 +1216,15 @@ public: ("__analyzer_cpython_dump_refcounts", std::make_unique<kf_analyzer_cpython_dump_refcounts> ()); } + + void + on_message (const analyzer_events::on_frame_popped &msg) final override + { + pyobj_refcnt_checker (msg.m_new_model, + msg.m_old_model, + msg.m_retval, + msg.m_ctxt); + } } cpython_sub; } // namespace ana @@ -1230,7 +1239,6 @@ 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); - region_model::register_pop_frame_callback(pyobj_refcnt_checker); g->get_channels ().analyzer_events_channel.add_subscriber (ana::cpython_sub); #else sorry_no_analyzer ();
