[libcxx] r303874 - Add support for shared_ptr<FunctionType>
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Thu May 25 08:43:31 PDT 2017
Author: epilk
Date: Thu May 25 10:43:31 2017
New Revision: 303874
URL: http://llvm.org/viewvc/llvm-project?rev=303874&view=rev
Log:
Add support for shared_ptr<FunctionType>
Fixes PR27566.
Differential revision: https://reviews.llvm.org/D30837
Added:
libcxx/trunk/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/
libcxx/trunk/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
Modified:
libcxx/trunk/include/memory
libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
Modified: libcxx/trunk/include/memory
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=303874&r1=303873&r2=303874&view=diff
==============================================================================
--- libcxx/trunk/include/memory (original)
+++ libcxx/trunk/include/memory Thu May 25 10:43:31 2017
@@ -2251,6 +2251,8 @@ void swap(__compressed_pair<_T1, _T2>& _
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 @@ __shared_ptr_emplace<_Tp, _Alloc>::__on_
__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 @@ public:
#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 @@ private:
}
}
- _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 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p,
: __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 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _D
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 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t __
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 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_
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 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_
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();
Added: libcxx/trunk/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp?rev=303874&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp (added)
+++ libcxx/trunk/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp Thu May 25 10:43:31 2017
@@ -0,0 +1,40 @@
+#include <memory>
+
+template <int> struct Tag {};
+
+template <int ID>
+using SPtr = std::shared_ptr<void(Tag<ID>)>;
+
+template <int ID>
+using FnType = void(Tag<ID>);
+
+template <int ID>
+void TestFn(Tag<ID>) {}
+
+template <int ID>
+FnType<ID>* getFn() {
+ return &TestFn<ID>;
+}
+
+struct Deleter {
+ template <class Tp>
+ void operator()(Tp) const {
+ using RawT = typename std::remove_pointer<Tp>::type;
+ static_assert(std::is_function<RawT>::value ||
+ std::is_null_pointer<RawT>::value, "");
+ }
+};
+
+int main() {
+ {
+ SPtr<0> s; // OK
+ SPtr<1> s1(nullptr); // OK
+ SPtr<2> s2(getFn<2>(), Deleter{}); // OK
+ SPtr<3> s3(nullptr, Deleter{}); // OK
+ }
+ // expected-error at memory:* 2 {{static_assert failed "default_delete cannot be instantiated for function types"}}
+ {
+ SPtr<4> s4(getFn<4>()); // expected-note {{requested here}}
+ SPtr<5> s5(getFn<5>(), std::default_delete<FnType<5>>{}); // expected-note {{requested here}}
+ }
+}
Modified: libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp?rev=303874&r1=303873&r2=303874&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp Thu May 25 10:43:31 2017
@@ -45,6 +45,13 @@ struct Foo
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 @@ int main()
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;
{
More information about the cfe-commits
mailing list