Only set std::enable_shared_from_this member once.
* include/bits/shared_ptr.h (__enable_shared_from_this_helper): Use nullptr. * include/bits/shared_ptr_base.h (weak_ptr::_M_assign): Don't assign if ownership is already shared with a shared_ptr object. (__enable_shared_from_this_helper): Use nullptr. * testsuite/20_util/enable_shared_from_this/members/const.cc: New. * testsuite/20_util/enable_shared_from_this/members/reinit.cc: New. * testsuite/20_util/enable_shared_from_this/requirements/ explicit_instantiation.cc: Instantiate with const and incomplete types. From-SVN: r227232
This commit is contained in:
parent
2d1a0c68ab
commit
6bc41b268e
6 changed files with 131 additions and 4 deletions
|
@ -1,5 +1,15 @@
|
|||
2015-08-26 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/bits/shared_ptr.h (__enable_shared_from_this_helper): Use
|
||||
nullptr.
|
||||
* include/bits/shared_ptr_base.h (weak_ptr::_M_assign): Don't assign
|
||||
if ownership is already shared with a shared_ptr object.
|
||||
(__enable_shared_from_this_helper): Use nullptr.
|
||||
* testsuite/20_util/enable_shared_from_this/members/const.cc: New.
|
||||
* testsuite/20_util/enable_shared_from_this/members/reinit.cc: New.
|
||||
* testsuite/20_util/enable_shared_from_this/requirements/
|
||||
explicit_instantiation.cc: Instantiate with const and incomplete types.
|
||||
|
||||
* include/debug/map.h (map::try_emplace, map::insert_or_assign):
|
||||
Define.
|
||||
* include/debug/unordered_map (unordered_map::try_emplace,
|
||||
|
|
|
@ -588,7 +588,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
const enable_shared_from_this* __pe,
|
||||
const _Tp1* __px) noexcept
|
||||
{
|
||||
if (__pe != 0)
|
||||
if (__pe != nullptr)
|
||||
__pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
|
||||
}
|
||||
|
||||
|
|
|
@ -1468,8 +1468,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
void
|
||||
_M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
|
||||
{
|
||||
_M_ptr = __ptr;
|
||||
_M_refcount = __refcount;
|
||||
if (use_count() == 0)
|
||||
{
|
||||
_M_ptr = __ptr;
|
||||
_M_refcount = __refcount;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
|
||||
|
@ -1549,7 +1552,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
const __enable_shared_from_this* __pe,
|
||||
const _Tp1* __px) noexcept
|
||||
{
|
||||
if (__pe != 0)
|
||||
if (__pe != nullptr)
|
||||
__pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++11" }
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T, typename U>
|
||||
bool
|
||||
share_ownership(const std::shared_ptr<T>& p1, const std::shared_ptr<U>& p2)
|
||||
{
|
||||
return !p1.owner_before(p2) && !p2.owner_before(p1);
|
||||
}
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
struct X : public std::enable_shared_from_this<X> { };
|
||||
using CX = const X;
|
||||
std::shared_ptr<CX> p(new X);
|
||||
VERIFY( share_ownership(p->shared_from_this(), p) );
|
||||
p.reset(new CX);
|
||||
VERIFY( share_ownership(p->shared_from_this(), p) );
|
||||
auto p2 = std::const_pointer_cast<X>(p)->shared_from_this();
|
||||
VERIFY( share_ownership(p2, p) );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
struct X;
|
||||
using CX = const X;
|
||||
struct X : public std::enable_shared_from_this<CX> { };
|
||||
std::shared_ptr<CX> p(new X);
|
||||
VERIFY( share_ownership(p->shared_from_this(), p) );
|
||||
p.reset(new CX);
|
||||
VERIFY( share_ownership(p->shared_from_this(), p) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++11" }
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
struct X : public std::enable_shared_from_this<X> { };
|
||||
|
||||
bool
|
||||
share_ownership(const std::shared_ptr<X>& p1, const std::shared_ptr<X>& p2)
|
||||
{
|
||||
return !p1.owner_before(p2) && !p2.owner_before(p1);
|
||||
}
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
std::shared_ptr<X> p1(new X);
|
||||
VERIFY( share_ownership( p1->shared_from_this(), p1 ) );
|
||||
{
|
||||
std::shared_ptr<X> p2(p1.get(), [](X*){});
|
||||
// The weak_ptr member of the enable_shared_from_this base should not
|
||||
// be reset by creating a second control block that owns the pointer.
|
||||
VERIFY( share_ownership( p2->shared_from_this(), p1 ) );
|
||||
}
|
||||
VERIFY( share_ownership( p1->shared_from_this(), p1 ) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
}
|
|
@ -21,3 +21,8 @@
|
|||
#include <memory>
|
||||
|
||||
template class std::enable_shared_from_this<int>;
|
||||
template class std::enable_shared_from_this<const int>;
|
||||
|
||||
class Incomplete;
|
||||
template class std::enable_shared_from_this<Incomplete>;
|
||||
template class std::enable_shared_from_this<const Incomplete>;
|
||||
|
|
Loading…
Add table
Reference in a new issue