diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2017-11-09 09:22:55 +0100 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2017-11-09 09:22:55 +0100 |
commit | 299e339f95da6efaf87473b76158eb13fb5ef5ad (patch) | |
tree | e75da1432c997b9de5a1123f2788bba4dcee8f26 | |
parent | 01925e38ad393981d056ab9cda8e044c84864212 (diff) | |
download | sigc++-299e339f95da6efaf87473b76158eb13fb5ef5ad.tar.gz |
slot_base::set_parent(): Create a dummy slot_rep if necessary
set_parent() must always store the supplied parent pointer and cleanup
function pointer, or else there may be a memory leak. The pointers are
stored in slot_rep. Bug 167714
-rw-r--r-- | sigc++/functors/slot_base.cc | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/sigc++/functors/slot_base.cc b/sigc++/functors/slot_base.cc index 4c521a8..106f229 100644 --- a/sigc++/functors/slot_base.cc +++ b/sigc++/functors/slot_base.cc @@ -20,6 +20,18 @@ #include <sigc++/functors/slot_base.h> #include <sigc++/weak_raw_ptr.h> +namespace +{ +// Used by slot_base::set_parent() when a slot_base without a rep_ is assigned a parent. +class dummy_slot_rep : public sigc::internal::slot_rep +{ +public: + dummy_slot_rep() : slot_rep(nullptr) {} + sigc::internal::slot_rep* clone() const override { return new dummy_slot_rep(); } + void destroy() override {} +}; +} // anonymous namespace + namespace sigc { namespace internal @@ -243,8 +255,9 @@ slot_base::operator=(slot_base&& src) void slot_base::set_parent(notifiable* parent, notifiable::func_destroy_notify cleanup) const noexcept { - if (rep_) - rep_->set_parent(parent, cleanup); + if (!rep_) + rep_ = new dummy_slot_rep(); + rep_->set_parent(parent, cleanup); } void |