Add support for shared_ptr<FunctionType>
Fixes PR27566.
Differential revision: https://reviews.llvm.org/D30837
llvm-svn: 303874
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 72d0d603fbaefe23c10624b25ef9addacf9fd1f1
diff --git a/include/memory b/include/memory
index 4201c92..31dc73d 100644
--- a/include/memory
+++ b/include/memory
@@ -2251,6 +2251,8 @@
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS default_delete {
+ static_assert(!is_function<_Tp>::value,
+ "default_delete cannot be instantiated for function types");
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY constexpr default_delete() noexcept = default;
#else
@@ -3653,6 +3655,18 @@
__a.deallocate(_PTraits::pointer_to(*this), 1);
}
+struct __shared_ptr_dummy_rebind_allocator_type;
+template <>
+class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
+{
+public:
+ template <class _Other>
+ struct rebind
+ {
+ typedef allocator<_Other> other;
+ };
+};
+
template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
template<class _Tp>
@@ -3921,6 +3935,17 @@
#endif // _LIBCPP_HAS_NO_VARIADICS
private:
+ template <class _Yp, bool = is_function<_Yp>::value>
+ struct __shared_ptr_default_allocator
+ {
+ typedef allocator<_Yp> type;
+ };
+
+ template <class _Yp>
+ struct __shared_ptr_default_allocator<_Yp, true>
+ {
+ typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
+ };
template <class _Yp, class _OrigPtr>
_LIBCPP_INLINE_VISIBILITY
@@ -3939,8 +3964,7 @@
}
}
- _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;
@@ -3972,8 +3996,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);
}
@@ -3988,8 +4013,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
}
@@ -4010,8 +4036,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 (...)
@@ -4179,8 +4206,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();
@@ -4208,10 +4236,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();