From 70826946ea1908954914bb09e27e40139f49be59 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 20 Nov 2009 21:23:02 +0000 Subject: [PATCH] re PR libstdc++/42019 (shared_ptr can not be used with -fno-rtti) 2009-11-20 Jonathan Wakely 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 --- libstdc++-v3/ChangeLog | 11 +++- libstdc++-v3/include/bits/shared_ptr.h | 8 ++- libstdc++-v3/include/bits/shared_ptr_base.h | 46 ++++++++++++++- libstdc++-v3/include/tr1/shared_ptr.h | 16 +++++- .../20_util/shared_ptr/misc/42019.cc | 56 +++++++++++++++++++ .../shared_ptr/misc/42019.cc | 35 ++++++++++++ 6 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/misc/42019.cc create mode 100644 libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/misc/42019.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3ae63049b92..18fbe843db7 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,4 +1,13 @@ -2009-11-21 Paolo Carlini +2009-11-20 Jonathan Wakely + + 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 * src/compatibility-c++0x.cc (_Fnv_hash<4>, _Fnv_hash<8>): Add. diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index 796df14c2c4..60fdf2fcbb0 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -76,7 +76,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template 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 + } /** diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index b8083e405c8..ff1282d5620 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -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(&_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 @@ -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 + struct _Deleter + { + void operator()(_Tp* __ptr) + { + _M_alloc.destroy(__ptr); + _M_alloc.deallocate(__ptr, 1); + } + _Alloc _M_alloc; + }; + + template + __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 diff --git a/libstdc++-v3/include/tr1/shared_ptr.h b/libstdc++-v3/include/tr1/shared_ptr.h index ba2cacae4ed..6176b5e4814 100644 --- a/libstdc++-v3/include/tr1/shared_ptr.h +++ b/libstdc++-v3/include/tr1/shared_ptr.h @@ -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 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 diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/misc/42019.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/42019.cc new file mode 100644 index 00000000000..bea1771d258 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/42019.cc @@ -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 +// . + +// 20.8.15.2 Template class shared_ptr [util.smartptr.shared] + +#include +#include + +// libstdc++/42019 + +class A {}; + +struct B { + explicit B(int i) : i(i) { } + int i; +}; + +void test01() +{ + bool test __attribute__((unused)) = true; + + std::shared_ptr spA = std::make_shared(); + + VERIFY( spA.get() != 0 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + + std::shared_ptr spB = std::make_shared(99); + + VERIFY( spB->i == 99 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/misc/42019.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/misc/42019.cc new file mode 100644 index 00000000000..c52aa8af65e --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/misc/42019.cc @@ -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 +// . + +// TR1 2.2.2 Template class shared_ptr [tr.util.smartptr.shared] + +#include + +// libstdc++/42019 +class A {}; + +void test01() +{ + std::tr1::shared_ptr spA; +} + +int main() +{ + test01(); + return 0; +}