From a5cee4808e6598c60068f798542e3c9f690321f2 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 7 Oct 2005 15:55:17 +0000 Subject: [PATCH] Fix libstdc++/24196 for ext/vstring/rc by returning to the behavior of basic_string pre-2003-06-13... 2005-10-07 Paolo Carlini Fix libstdc++/24196 for ext/vstring/rc by returning to the behavior of basic_string pre-2003-06-13; remove fully-dynamic-string stuff. * include/ext/rc_string_base.h (_M_refcopy): Move inside the _Rep class and remove code in macro. (__rc_string_base()): Construct with _S_empty_rep()._M_refcopy(). (_M_dispose, _M_leak_hard): Remove code in macro. (_S_construct): Return _S_empty_rep()._M_refcopy() for empty string. (_M_grab): Adjust. * include/ext/rc_string_base.h (_Rep::_M_refdata()): Minor tweak, mark throw(). From-SVN: r105090 --- libstdc++-v3/ChangeLog | 14 ++++++ libstdc++-v3/include/ext/rc_string_base.h | 54 ++++++++--------------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9732bc008e9..5c2ad8d9d3e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2005-10-07 Paolo Carlini + + Fix libstdc++/24196 for ext/vstring/rc by returning to the behavior + of basic_string pre-2003-06-13; remove fully-dynamic-string stuff. + * include/ext/rc_string_base.h (_M_refcopy): Move inside the + _Rep class and remove code in macro. + (__rc_string_base()): Construct with _S_empty_rep()._M_refcopy(). + (_M_dispose, _M_leak_hard): Remove code in macro. + (_S_construct): Return _S_empty_rep()._M_refcopy() for empty string. + (_M_grab): Adjust. + + * include/ext/rc_string_base.h (_Rep::_M_refdata()): Minor tweak, + mark throw(). + 2005-10-07 Benjamin Kosnik * docs/doxygen/user.cfg.in: Update to Doyxygen 1.4.4. diff --git a/libstdc++-v3/include/ext/rc_string_base.h b/libstdc++-v3/include/ext/rc_string_base.h index 3e9c88719c1..0b35e383f6a 100644 --- a/libstdc++-v3/include/ext/rc_string_base.h +++ b/libstdc++-v3/include/ext/rc_string_base.h @@ -134,9 +134,16 @@ namespace __gnu_cxx typedef typename _Alloc::template rebind::other _Raw_alloc; _CharT* - _M_refdata() + _M_refdata() throw() { return reinterpret_cast<_CharT*>(this + 1); } + _CharT* + _M_refcopy() throw() + { + __atomic_add(&_M_refcount, 1); + return _M_refdata(); + } // XXX MT + void _M_set_length(size_type __n) { @@ -190,31 +197,18 @@ namespace __gnu_cxx _M_rep() const { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); } - _CharT* - _M_refcopy() const throw() - { -#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING - if (__builtin_expect(_M_rep() != &_S_empty_rep(), false)) -#endif - __atomic_add(&_M_rep()->_M_refcount, 1); - return _M_data(); - } // XXX MT - _CharT* _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) const { return (!_M_is_leaked() && __alloc1 == __alloc2) - ? _M_refcopy() : _M_rep()->_M_clone(__alloc1); + ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc1); } void _M_dispose(const _Alloc& __a) { -#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING - if (__builtin_expect(_M_rep() != &_S_empty_rep(), false)) -#endif - if (__exchange_and_add(&_M_rep()->_M_refcount, -1) <= 0) - _M_rep()->_M_destroy(__a); + if (__exchange_and_add(&_M_rep()->_M_refcount, -1) <= 0) + _M_rep()->_M_destroy(__a); } // XXX MT void @@ -303,11 +297,8 @@ namespace __gnu_cxx } __rc_string_base() -#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING - : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } -#else - : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { } -#endif + : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { } + __rc_string_base(const _Alloc& __a); __rc_string_base(const __rc_string_base& __rcs); @@ -486,10 +477,6 @@ namespace __gnu_cxx __rc_string_base<_CharT, _Traits, _Alloc>:: _M_leak_hard() { -#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING - if (_M_rep() == &_S_empty_rep()) - return; -#endif if (_M_is_shared()) _M_mutate(0, 0, 0); _M_set_leaked(); @@ -506,10 +493,9 @@ namespace __gnu_cxx _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, std::input_iterator_tag) { -#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING if (__beg == __end && __a == _Alloc()) - return _S_empty_rep()._M_refdata(); -#endif + return _S_empty_rep()._M_refcopy(); + // Avoid reallocation for common case. _CharT __buf[128]; size_type __len = 0; @@ -552,10 +538,9 @@ namespace __gnu_cxx _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, std::forward_iterator_tag) { -#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING if (__beg == __end && __a == _Alloc()) - return _S_empty_rep()._M_refdata(); -#endif + return _S_empty_rep()._M_refcopy(); + // NB: Not required, but considered best practice. if (__builtin_expect(__is_null_p(__beg) && __beg != __end, 0)) std::__throw_logic_error(__N("__rc_string_base::" @@ -581,10 +566,9 @@ namespace __gnu_cxx __rc_string_base<_CharT, _Traits, _Alloc>:: _S_construct(size_type __n, _CharT __c, const _Alloc& __a) { -#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING if (__n == 0 && __a == _Alloc()) - return _S_empty_rep()._M_refdata(); -#endif + return _S_empty_rep()._M_refcopy(); + // Check for out_of_range and length_error exceptions. _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); if (__n)