summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2017-11-09 09:22:55 +0100
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2017-11-09 09:22:55 +0100
commit299e339f95da6efaf87473b76158eb13fb5ef5ad (patch)
treee75da1432c997b9de5a1123f2788bba4dcee8f26
parent01925e38ad393981d056ab9cda8e044c84864212 (diff)
downloadsigc++-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.cc17
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