diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2014-11-12 19:41:36 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2014-11-12 19:41:36 +0000 |
commit | d8af84e67b08377cf813eb4d4bbf8ae2e8226fa1 (patch) | |
tree | 3e204d7b474dd6286194676bad64a5cf2b9c3f37 /libstdc++-v3 | |
parent | 3e147937eac9eb182c419a4bd4f5155b341d7188 (diff) | |
download | gcc-d8af84e67b08377cf813eb4d4bbf8ae2e8226fa1.zip gcc-d8af84e67b08377cf813eb4d4bbf8ae2e8226fa1.tar.gz gcc-d8af84e67b08377cf813eb4d4bbf8ae2e8226fa1.tar.bz2 |
Implement resolutions of LWG 2399, 2400 and 2401.
* include/bits/shared_ptr.h (shared_ptr, weak_ptr): Define
_Convertible alias template to simplify constraints.
(shared_ptr(unique_ptr<TD>&&)): Constrain (LWG 2399).
* include/bits/shared_ptr_base.h: Likewise.
(_Sp_counted_deleter::_M_get_deleter()): Use addressof (LWG 2400).
* include/std/functional (function::operator=(nullptr_t)): Add
noexcept (LWG 2401).
* testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust dg-error.
* testsuite/20_util/shared_ptr/cons/void_neg.cc: Adjust dg-error.
From-SVN: r217442
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr.h | 28 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr_base.h | 32 | ||||
-rw-r--r-- | libstdc++-v3/include/std/functional | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc | 2 |
6 files changed, 50 insertions, 26 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 30a3ba6..8960ef74 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -7,6 +7,16 @@ * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust dg-error. * testsuite/20_util/shared_ptr/cons/void_neg.cc: Adjust dg-error. + * include/bits/shared_ptr.h (shared_ptr, weak_ptr): Define + _Convertible alias template to simplify constraints. + (shared_ptr(unique_ptr<TD>&&)): Constrain (LWG 2399). + * include/bits/shared_ptr_base.h: Likewise. + (_Sp_counted_deleter::_M_get_deleter()): Use addressof (LWG 2400). + * include/std/functional (function::operator=(nullptr_t)): Add + noexcept (LWG 2401). + * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust dg-error. + * testsuite/20_util/shared_ptr/cons/void_neg.cc: Adjust dg-error. + 2014-11-12 Jonathan Wakely <jwakely@redhat.com> PR c++/33911 diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index c2d56eb..22cb58a 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -92,6 +92,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> class shared_ptr : public __shared_ptr<_Tp> { + template<typename _Ptr> + using _Convertible + = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type; + public: /** * @brief Construct an empty %shared_ptr. @@ -213,8 +217,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __r A %shared_ptr. * @post get() == __r.get() && use_count() == __r.use_count() */ - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> shared_ptr(const shared_ptr<_Tp1>& __r) noexcept : __shared_ptr<_Tp>(__r) { } @@ -231,8 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __r A %shared_ptr rvalue. * @post *this contains the old value of @a __r, @a __r is empty. */ - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> shared_ptr(shared_ptr<_Tp1>&& __r) noexcept : __shared_ptr<_Tp>(std::move(__r)) { } @@ -253,7 +255,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION shared_ptr(std::auto_ptr<_Tp1>&& __r); #endif - template<typename _Tp1, typename _Del> + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2399. shared_ptr's constructor from unique_ptr should be constrained + template<typename _Tp1, typename _Del, typename + = _Convertible<typename unique_ptr<_Tp1, _Del>::pointer>> shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) : __shared_ptr<_Tp>(std::move(__r)) { } @@ -464,25 +469,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> class weak_ptr : public __weak_ptr<_Tp> { + template<typename _Ptr> + using _Convertible + = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type; + public: constexpr weak_ptr() noexcept = default; - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> weak_ptr(const shared_ptr<_Tp1>& __r) noexcept : __weak_ptr<_Tp>(__r) { } weak_ptr(const weak_ptr&) noexcept = default; - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> weak_ptr(const weak_ptr<_Tp1>& __r) noexcept : __weak_ptr<_Tp>(__r) { } weak_ptr(weak_ptr&&) noexcept = default; - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> weak_ptr(weak_ptr<_Tp1>&& __r) noexcept : __weak_ptr<_Tp>(std::move(__r)) { } diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index ea74000..fe397d0 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -477,7 +477,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_get_deleter(const std::type_info& __ti) noexcept { #ifdef __GXX_RTTI - return __ti == typeid(_Deleter) ? &_M_impl._M_del() : nullptr; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2400. shared_ptr's get_deleter() should use addressof() + return __ti == typeid(_Deleter) + ? std::__addressof(_M_impl._M_del()) + : nullptr; #else return nullptr; #endif @@ -862,6 +866,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, _Lock_policy _Lp> class __shared_ptr { + template<typename _Ptr> + using _Convertible + = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type; + public: typedef _Tp element_type; @@ -916,8 +924,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __shared_ptr& operator=(const __shared_ptr&) noexcept = default; ~__shared_ptr() = default; - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) { } @@ -929,8 +936,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __r._M_ptr = 0; } - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount() { @@ -950,7 +956,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // If an exception is thrown this constructor has no effect. - template<typename _Tp1, typename _Del> + template<typename _Tp1, typename _Del, typename + = _Convertible<typename unique_ptr<_Tp1, _Del>::pointer>> __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) : _M_ptr(__r.get()), _M_refcount() { @@ -1331,6 +1338,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, _Lock_policy _Lp> class __weak_ptr { + template<typename _Ptr> + using _Convertible + = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type; + public: typedef _Tp element_type; @@ -1356,14 +1367,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // // It is not possible to avoid spurious access violations since // in multithreaded programs __r._M_ptr may be invalidated at any point. - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept : _M_refcount(__r._M_refcount) { _M_ptr = __r.lock().get(); } - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) { } @@ -1372,8 +1381,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) { __r._M_ptr = nullptr; } - template<typename _Tp1, typename = typename - std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> + template<typename _Tp1, typename = _Convertible<_Tp1*>> __weak_ptr(__weak_ptr<_Tp1, _Lp>&& __r) noexcept : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount)) { __r._M_ptr = nullptr; } diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index e711350..71d97ad 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -2102,7 +2102,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) * The target of @c *this is deallocated, leaving it empty. */ function& - operator=(nullptr_t) + operator=(nullptr_t) noexcept { if (_M_manager) { diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc index be33279..d354d20 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc @@ -32,7 +32,7 @@ void test01() { X* px = 0; std::shared_ptr<X> p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 878 } + // { dg-error "incomplete" "" { target *-*-* } 886 } std::shared_ptr<X> p9(ap()); // { dg-error "here" } // { dg-error "incomplete" "" { target *-*-* } 307 } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc index 17e036f..d833aea 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc @@ -25,5 +25,5 @@ void test01() { std::shared_ptr<void> p((void*)nullptr); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 877 } + // { dg-error "incomplete" "" { target *-*-* } 885 } } |