From 8628d985427ccda25b129b43e3082aa3758d92e6 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 9 Mar 2015 15:44:22 +0200 Subject: [PATCH] shared_ptr: fix reference count loss when creating a derived type with e_s_f_t make_shared() has a special case for detecting a created class deriving from enable_shared_from_this<>, so it can point the refcount pointer into the object's data area instead of creating a shared_ptr_count_base for it. The code, however, fails to detect a creating class deriving indirectly from enable_shared_from_this: struct base : enable_shared_from_this {}; struct derived : base {}; make_shared(); // <- allocates independent refcount The result is that the object reference counter lives in two locations. Fix by detecting the derived class case as well. --- core/shared_ptr.hh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/shared_ptr.hh b/core/shared_ptr.hh index 032d001775..a5f9c24dba 100644 --- a/core/shared_ptr.hh +++ b/core/shared_ptr.hh @@ -274,6 +274,9 @@ public: template friend class shared_ptr; + + template + friend struct shared_ptr_make_helper; }; template @@ -418,7 +421,8 @@ template struct shared_ptr_make_helper { template static shared_ptr make(A&&... a) { - return shared_ptr(new T(std::forward(a)...)); + auto p = new T(std::forward(a)...); + return shared_ptr(p, p); } }; @@ -426,7 +430,7 @@ template inline shared_ptr make_shared(A&&... a) { - using helper = shared_ptr_make_helper, T>::value>; + using helper = shared_ptr_make_helper::value>; return helper::make(std::forward(a)...); } @@ -434,7 +438,7 @@ template inline shared_ptr make_shared(T&& a) { - using helper = shared_ptr_make_helper, T>::value>; + using helper = shared_ptr_make_helper::value>; return helper::make(std::forward(a)); }