mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 03:50:27 +08:00
re PR libstdc++/42019 (shared_ptr can not be used with -fno-rtti)
2009-11-20 Jonathan Wakely <jwakely.gcc@gmail.com> PR libstdc++/42019 * include/tr1/shared_ptr.h: Only use typeid when RTTI is enabled. * include/bits/shared_ptr_base.h: Likewise. * include/bits/shared_ptr.h: Likewise. * testsuite/tr1/2_general_utilities/shared_ptr/misc/42019.cc: New. * testsuite/20_util/shared_ptr/misc/42019.cc: New. From-SVN: r154377
This commit is contained in:
parent
d547364305
commit
70826946ea
@ -1,4 +1,13 @@
|
||||
2009-11-21 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
2009-11-20 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||
|
||||
PR libstdc++/42019
|
||||
* include/tr1/shared_ptr.h: Only use typeid when RTTI is enabled.
|
||||
* include/bits/shared_ptr_base.h: Likewise.
|
||||
* include/bits/shared_ptr.h: Likewise.
|
||||
* testsuite/tr1/2_general_utilities/shared_ptr/misc/42019.cc: New.
|
||||
* testsuite/20_util/shared_ptr/misc/42019.cc: New.
|
||||
|
||||
2009-11-20 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* src/compatibility-c++0x.cc (_Fnv_hash<4>, _Fnv_hash<8>): Add.
|
||||
|
||||
|
@ -76,7 +76,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
template<typename _Del, typename _Tp, _Lock_policy _Lp>
|
||||
inline _Del*
|
||||
get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
|
||||
{ return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
|
||||
{
|
||||
#ifdef __GXX_RTTI
|
||||
return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -151,7 +151,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
|
||||
virtual void*
|
||||
_M_get_deleter(const std::type_info& __ti)
|
||||
{ return __ti == typeid(_Deleter) ? &_M_del._M_del : 0; }
|
||||
{
|
||||
#ifdef __GXX_RTTI
|
||||
return __ti == typeid(_Deleter) ? &_M_del._M_del : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
_My_Deleter _M_del; // copy constructor must not throw
|
||||
@ -209,9 +215,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
virtual void*
|
||||
_M_get_deleter(const std::type_info& __ti)
|
||||
{
|
||||
#ifdef __GXX_RTTI
|
||||
return __ti == typeid(_Sp_make_shared_tag)
|
||||
? static_cast<void*>(&_M_storage)
|
||||
: _Base_type::_M_get_deleter(__ti);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
@ -740,6 +750,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
|
||||
{ return _M_refcount._M_less(__rhs._M_refcount); }
|
||||
|
||||
#ifdef __GXX_RTTI
|
||||
protected:
|
||||
// This constructor is non-standard, it is used by allocate_shared.
|
||||
template<typename _Alloc, typename... _Args>
|
||||
@ -753,6 +764,39 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
_M_ptr = static_cast<_Tp*>(__p);
|
||||
__enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
|
||||
}
|
||||
#else
|
||||
template<typename _Alloc>
|
||||
struct _Deleter
|
||||
{
|
||||
void operator()(_Tp* __ptr)
|
||||
{
|
||||
_M_alloc.destroy(__ptr);
|
||||
_M_alloc.deallocate(__ptr, 1);
|
||||
}
|
||||
_Alloc _M_alloc;
|
||||
};
|
||||
|
||||
template<typename _Alloc, typename... _Args>
|
||||
__shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
|
||||
: _M_ptr(), _M_refcount()
|
||||
{
|
||||
typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
|
||||
_Deleter<_Alloc2> __del = { _Alloc2(__a) };
|
||||
_M_ptr = __del._M_alloc.allocate(1);
|
||||
__try
|
||||
{
|
||||
__del._M_alloc.construct(_M_ptr, std::forward<_Args>(__args)...);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
__del._M_alloc.deallocate(_M_ptr, 1);
|
||||
__throw_exception_again;
|
||||
}
|
||||
__shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
|
||||
_M_refcount._M_swap(__count);
|
||||
__enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
|
||||
typename... _Args>
|
||||
|
@ -72,7 +72,13 @@ namespace tr1
|
||||
|
||||
virtual void*
|
||||
_M_get_deleter(const std::type_info& __ti)
|
||||
{ return __ti == typeid(_Deleter) ? &_M_del : 0; }
|
||||
{
|
||||
#ifdef __GXX_RTTI
|
||||
return __ti == typeid(_Deleter) ? &_M_del : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
_Sp_counted_base_impl(const _Sp_counted_base_impl&);
|
||||
@ -595,7 +601,13 @@ namespace tr1
|
||||
template<typename _Del, typename _Tp, _Lock_policy _Lp>
|
||||
inline _Del*
|
||||
get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
|
||||
{ return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
|
||||
{
|
||||
#ifdef __GXX_RTTI
|
||||
return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template<typename _Tp, _Lock_policy _Lp>
|
||||
|
56
libstdc++-v3/testsuite/20_util/shared_ptr/misc/42019.cc
Normal file
56
libstdc++-v3/testsuite/20_util/shared_ptr/misc/42019.cc
Normal file
@ -0,0 +1,56 @@
|
||||
// { dg-options "-std=gnu++0x -fno-rtti" }
|
||||
// Copyright (C) 2009 Free Software Foundation
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
// 20.8.15.2 Template class shared_ptr [util.smartptr.shared]
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// libstdc++/42019
|
||||
|
||||
class A {};
|
||||
|
||||
struct B {
|
||||
explicit B(int i) : i(i) { }
|
||||
int i;
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
std::shared_ptr<A> spA = std::make_shared<A>();
|
||||
|
||||
VERIFY( spA.get() != 0 );
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
std::shared_ptr<B> spB = std::make_shared<B>(99);
|
||||
|
||||
VERIFY( spB->i == 99 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
// { dg-options "-fno-rtti" }
|
||||
// Copyright (C) 2009 Free Software Foundation
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
// TR1 2.2.2 Template class shared_ptr [tr.util.smartptr.shared]
|
||||
|
||||
#include <tr1/memory>
|
||||
|
||||
// libstdc++/42019
|
||||
class A {};
|
||||
|
||||
void test01()
|
||||
{
|
||||
std::tr1::shared_ptr<A> spA;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user