diff options
author | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-10-07 15:55:17 +0000 |
---|---|---|
committer | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-10-07 15:55:17 +0000 |
commit | 7f586c25a2c90fdfb7fe6ebc5b0a5819dcb4ac3c (patch) | |
tree | 35667c891da9eb4b7fac1a83cb8b0d21303206c5 /libstdc++-v3 | |
parent | a978f42ad44d3866e6e7c0d306d0c6be2028e05c (diff) | |
download | gcc-7f586c25a2c90fdfb7fe6ebc5b0a5819dcb4ac3c.tar.gz |
2005-10-07 Paolo Carlini <pcarlini@suse.de>
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().
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105090 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 14 | ||||
-rw-r--r-- | 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 <pcarlini@suse.de> + + 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 <bkoz@redhat.com> * 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<size_type>::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) { @@ -191,30 +198,17 @@ namespace __gnu_cxx { 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) |