erik.pilkington updated this revision to Diff 91660. erik.pilkington added a comment.
In this new patch: - We only select `allocator<int>` when _Yp is a function type, fixing the ABI break @EricWF pointed out. - Only try to select a different allocator if we're using the `__shared_ptr_pointer` layout; `make_shared<void()>` doesn't make sense. - Improve the testcase Thanks for the feedback! Erik https://reviews.llvm.org/D30837 Files: include/memory test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp @@ -45,6 +45,13 @@ virtual ~Foo() = default; }; +struct Result {}; +static Result theFunction() { return Result(); } +static int resultDeletorCount; +static void resultDeletor(Result (*pf)()) { + assert(pf == theFunction); + ++resultDeletorCount; +} int main() { @@ -65,7 +72,11 @@ std::shared_ptr<const Foo> p2 = std::make_shared<const Foo>(); assert(p2.get()); } - + { // https://bugs.llvm.org/show_bug.cgi?id=27566 + std::shared_ptr<Result()> x(&theFunction, &resultDeletor); + std::shared_ptr<Result()> y(theFunction, resultDeletor); + } + assert(resultDeletorCount == 2); #if TEST_STD_VER >= 11 nc = globalMemCounter.outstanding_new; { Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -3884,13 +3884,25 @@ } } - _LIBCPP_INLINE_VISIBILITY - void __enable_weak_this(const volatile void*, const volatile void*) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {} template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr; template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr; }; +template <class _Tp, bool = is_function<_Tp>::value> +struct __shared_ptr_default_allocator; + +template <class _Tp> struct __shared_ptr_default_allocator<_Tp, false> +{ + typedef allocator<_Tp> type; +}; + +template <class _Tp> struct __shared_ptr_default_allocator<_Tp, true> +{ + typedef allocator<int> type; +}; + template<class _Tp> inline _LIBCPP_CONSTEXPR @@ -3916,8 +3928,9 @@ : __ptr_(__p) { unique_ptr<_Yp> __hold(__p); - typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), allocator<_Yp>()); + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; + typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), _AllocT()); __hold.release(); __enable_weak_this(__p, __p); } @@ -3932,8 +3945,9 @@ try { #endif // _LIBCPP_NO_EXCEPTIONS - typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Yp>()); + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; + typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS } @@ -3954,8 +3968,9 @@ try { #endif // _LIBCPP_NO_EXCEPTIONS - typedef __shared_ptr_pointer<nullptr_t, _Dp, allocator<_Tp> > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Tp>()); + typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; + typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -4094,8 +4109,9 @@ typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) : __ptr_(__r.get()) { - typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>()); + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; + typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), _AllocT()); __enable_weak_this(__r.get(), __r.get()); __r.release(); } @@ -4123,8 +4139,9 @@ else #endif { - typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>()); + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; + typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); __enable_weak_this(__r.get(), __r.get()); } __r.release(); @@ -4152,10 +4169,11 @@ else #endif { + typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; typedef __shared_ptr_pointer<_Yp*, reference_wrapper<typename remove_reference<_Dp>::type>, - allocator<_Yp> > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), allocator<_Yp>()); + _AllocT > _CntrlBlk; + __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), _AllocT()); __enable_weak_this(__r.get(), __r.get()); } __r.release();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits