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:
Jonathan Wakely 2009-11-20 21:23:02 +00:00
parent d547364305
commit 70826946ea
6 changed files with 167 additions and 5 deletions

View File

@ -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.

View File

@ -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
}
/**

View File

@ -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>

View File

@ -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>

View 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;
}

View File

@ -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;
}