diff -urN libstdc++-v3-orig/include/bits/basic_string.h libstdc++-v3/include/bits/basic_string.h --- libstdc++-v3-orig/include/bits/basic_string.h 2004-10-21 20:17:00.000000000 +0200 +++ libstdc++-v3/include/bits/basic_string.h 2004-10-24 10:35:29.000000000 +0200 @@ -185,6 +185,14 @@ _M_is_shared() const { return this->_M_refcount > 0; } + // True if source and destination do not overlap. + bool + _M_is_safe(const _CharT* __data, const _CharT* __s) const + { + return (less()(__s, __data) + || less()(__data + this->_M_length, __s)); + } + void _M_set_leaked() { this->_M_refcount = -1; } @@ -302,6 +310,13 @@ return __pos; } + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N(__s)); + } + // NB: _M_limit doesn't check for a bad __pos value. size_type _M_limit(size_type __pos, size_type __off) const @@ -310,6 +325,35 @@ return __testoff ? __off : this->size() - __pos; } + // When __n = 1 way faster than the general multichar + // traits_type::copy/move/assign. + static void + _M_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _M_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _M_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template @@ -330,11 +374,11 @@ static void _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) - { traits_type::copy(__p, __k1, __k2 - __k1); } + { _M_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) - { traits_type::copy(__p, __k1, __k2 - __k1); } + { _M_copy(__p, __k1, __k2 - __k1); } void _M_mutate(size_type __pos, size_type __len1, size_type __len2); @@ -721,7 +765,10 @@ */ basic_string& operator+=(_CharT __c) - { return this->append(size_type(1), __c); } + { + this->push_back(__c); + return *this; + } /** * @brief Append a string to this string. @@ -729,7 +776,19 @@ * @return Reference to this string. */ basic_string& - append(const basic_string& __str); + append(const basic_string& __str) + { + const size_type __size = __str.size(); + if (__size) + { + const size_type __len = __size + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data(), __size); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } /** * @brief Append a substring. @@ -777,7 +836,18 @@ */ basic_string& append(size_type __n, _CharT __c) - { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + { + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_assign(_M_data() + this->size(), __n, __c); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } /** * @brief Append a range of characters. @@ -798,7 +868,13 @@ */ void push_back(_CharT __c) - { _M_replace_aux(this->size(), size_type(0), size_type(1), __c); } + { + const size_type __len = 1 + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + traits_type::assign(_M_data()[this->size()], __c); + _M_rep()->_M_set_length_and_sharable(__len); + } /** * @brief Set value to contents of another string. @@ -806,7 +882,18 @@ * @return Reference to this string. */ basic_string& - assign(const basic_string& __str); + assign(const basic_string& __str) + { + if (_M_rep() != __str._M_rep()) + { + // XXX MT + const allocator_type __a = this->get_allocator(); + _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + return *this; + } /** * @brief Set value to a substring of a string. @@ -909,7 +996,8 @@ * of the string doesn't change if an error is thrown. */ template - void insert(iterator __p, _InputIterator __beg, _InputIterator __end) + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) { this->replace(__p, __p, __beg, __end); } /** @@ -1370,13 +1458,10 @@ _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c) { - if (this->max_size() - (this->size() - __n1) < __n2) - __throw_length_error(__N("basic_string::_M_replace_aux")); + _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); _M_mutate(__pos1, __n1, __n2); - if (__n2 == 1) - _M_data()[__pos1] = __c; - else if (__n2) - traits_type::assign(_M_data() + __pos1, __n2, __c); + if (__n2) + _M_assign(_M_data() + __pos1, __n2, __c); return *this; } @@ -1385,10 +1470,8 @@ size_type __n2) { _M_mutate(__pos1, __n1, __n2); - if (__n2 == 1) - _M_data()[__pos1] = *__s; - else if (__n2) - traits_type::copy(_M_data() + __pos1, __s, __n2); + if (__n2) + _M_copy(_M_data() + __pos1, __s, __n2); return *this; } diff -urN libstdc++-v3-orig/include/bits/basic_string.tcc libstdc++-v3/include/bits/basic_string.tcc --- libstdc++-v3-orig/include/bits/basic_string.tcc 2004-10-21 23:36:37.000000000 +0200 +++ libstdc++-v3/include/bits/basic_string.tcc 2004-10-24 17:34:06.000000000 +0200 @@ -101,7 +101,7 @@ ++__beg; } _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); - traits_type::copy(__r->_M_refdata(), __buf, __len); + _M_copy(__r->_M_refdata(), __buf, __len); try { while (__beg != __end) @@ -110,8 +110,7 @@ { // Allocate more space. _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); - traits_type::copy(__another->_M_refdata(), - __r->_M_refdata(), __len); + _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); __r->_M_destroy(__a); __r = __another; } @@ -170,7 +169,7 @@ // Check for out_of_range and length_error exceptions. _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); if (__n) - traits_type::assign(__r->_M_refdata(), __n, __c); + _M_assign(__r->_M_refdata(), __n, __c); __r->_M_set_length_and_sharable(__n); return __r->_M_refdata(); @@ -243,42 +242,69 @@ template basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: - assign(const basic_string& __str) + assign(const _CharT* __s, size_type __n) { - if (_M_rep() != __str._M_rep()) + __glibcxx_requires_string_len(__s, __n); + _M_check_length(this->size(), __n, "basic_string::assign"); + if (_M_rep()->_M_is_safe(_M_data(), __s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(size_type(0), this->size(), __s, __n); + else { - // XXX MT - const allocator_type __a = this->get_allocator(); - _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); - _M_rep()->_M_dispose(__a); - _M_data(__tmp); + // Work in-place. + const size_type __pos = __s - _M_data(); + if (__pos >= __n) + traits_type::copy(_M_data(), __s, __n); + else if (__pos) + traits_type::move(_M_data(), __s, __n); + _M_rep()->_M_set_length_and_sharable(__n); + return *this; + } + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + { + if (_M_rep()->_M_is_safe(_M_data(), __s)) + this->reserve(__len); + else + { + const size_type __off = __s - _M_data(); + this->reserve(__len); + __s = _M_data() + __off; + } + } + _M_copy(_M_data() + this->size(), __s, __n); + _M_rep()->_M_set_length_and_sharable(__len); } return *this; } - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - assign(const _CharT* __s, size_type __n) - { - __glibcxx_requires_string_len(__s, __n); - if (__n > this->max_size()) - __throw_length_error(__N("basic_string::assign")); - if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) - || less()(_M_data() + this->size(), __s)) - return _M_replace_safe(size_type(0), this->size(), __s, __n); - else - { - // Work in-place - const size_type __pos = __s - _M_data(); - if (__pos >= __n) - traits_type::copy(_M_data(), __s, __n); - else if (__pos) - traits_type::move(_M_data(), __s, __n); - _M_rep()->_M_set_length_and_sharable(__n); - return *this; - } - } + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str, size_type __pos, size_type __n) + { + __str._M_check(__pos, "basic_string::append"); + __n = __str._M_limit(__pos, __n); + if (__n) + { + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } template basic_string<_CharT, _Traits, _Alloc>& @@ -287,29 +313,25 @@ { __glibcxx_requires_string_len(__s, __n); _M_check(__pos, "basic_string::insert"); - if (this->max_size() - this->size() < __n) - __throw_length_error(__N("basic_string::insert")); - if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) - || less()(_M_data() + this->size(), __s)) + _M_check_length(size_type(0), __n, "basic_string::insert"); + if (_M_rep()->_M_is_safe(_M_data(), __s) || _M_rep()->_M_is_shared()) return _M_replace_safe(__pos, size_type(0), __s, __n); else { - // Work in-place. If _M_mutate reallocates the string, __s - // does not point anymore to valid data, therefore we save its - // offset, then we restore it. + // Work in-place. const size_type __off = __s - _M_data(); _M_mutate(__pos, 0, __n); __s = _M_data() + __off; _CharT* __p = _M_data() + __pos; if (__s + __n <= __p) - traits_type::copy(__p, __s, __n); + _M_copy(__p, __s, __n); else if (__s >= __p) - traits_type::copy(__p, __s + __n, __n); + _M_copy(__p, __s + __n, __n); else { const size_type __nleft = __p - __s; - traits_type::copy(__p, __s, __nleft); - traits_type::copy(__p + __nleft, __p + __n, __n - __nleft); + _M_copy(__p, __s, __nleft); + _M_copy(__p + __nleft, __p + __n, __n - __nleft); } return *this; } @@ -324,24 +346,18 @@ __glibcxx_requires_string_len(__s, __n2); _M_check(__pos, "basic_string::replace"); __n1 = _M_limit(__pos, __n1); - if (this->max_size() - (this->size() - __n1) < __n2) - __throw_length_error(__N("basic_string::replace")); + _M_check_length(__n1, __n2, "basic_string::replace"); bool __left; - if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) - || less()(_M_data() + this->size(), __s)) + if (_M_rep()->_M_is_safe(_M_data(), __s) || _M_rep()->_M_is_shared()) return _M_replace_safe(__pos, __n1, __s, __n2); else if ((__left = __s + __n2 <= _M_data() + __pos) || _M_data() + __pos + __n1 <= __s) { // Work in-place: non-overlapping case. - const size_type __off = __s - _M_data(); + size_type __off = __s - _M_data(); + __left ? __off : (__off += __n2 - __n1); _M_mutate(__pos, __n1, __n2); - if (__left) - traits_type::copy(_M_data() + __pos, - _M_data() + __off, __n2); - else - traits_type::copy(_M_data() + __pos, - _M_data() + __off + __n2 - __n1, __n2); + _M_copy(_M_data() + __pos, _M_data() + __off, __n2); return *this; } else @@ -396,19 +412,19 @@ _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); if (__pos) - traits_type::copy(__r->_M_refdata(), _M_data(), __pos); + _M_copy(__r->_M_refdata(), _M_data(), __pos); if (__how_much) - traits_type::copy(__r->_M_refdata() + __pos + __len2, - _M_data() + __pos + __len1, __how_much); + _M_copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); _M_rep()->_M_dispose(__a); _M_data(__r->_M_refdata()); } else if (__how_much && __len1 != __len2) { - // Work in-place - traits_type::move(_M_data() + __pos + __len2, - _M_data() + __pos + __len1, __how_much); + // Work in-place. + _M_move(_M_data() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); } _M_rep()->_M_set_length_and_sharable(__new_size); } @@ -420,8 +436,6 @@ { if (__res != this->capacity() || _M_rep()->_M_is_shared()) { - if (__res > this->max_size()) - __throw_length_error(__N("basic_string::reserve")); // Make sure we don't shrink below the current size if (__res < this->size()) __res = this->size(); @@ -539,7 +553,7 @@ _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, __alloc); if (this->_M_length) - traits_type::copy(__r->_M_refdata(), _M_refdata(), this->_M_length); + _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); __r->_M_set_length_and_sharable(this->_M_length); return __r->_M_refdata(); @@ -550,9 +564,8 @@ basic_string<_CharT, _Traits, _Alloc>:: resize(size_type __n, _CharT __c) { - if (__n > max_size()) - __throw_length_error(__N("basic_string::resize")); const size_type __size = this->size(); + _M_check_length(__size, __n, "basic_string::resize"); if (__size < __n) this->append(__n - __size, __c); else if (__n < __size) @@ -569,57 +582,11 @@ { const basic_string __s(__k1, __k2); const size_type __n1 = __i2 - __i1; - if (this->max_size() - (this->size() - __n1) < __s.size()) - __throw_length_error(__N("basic_string::_M_replace_dispatch")); + _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), __s.size()); } - - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - append(const basic_string& __str) - { - // Iff appending itself, string needs to pre-reserve the - // correct size so that _M_mutate does not clobber the - // pointer __str._M_data() formed here. - const size_type __size = __str.size(); - const size_type __len = __size + this->size(); - if (__len > this->capacity()) - this->reserve(__len); - return _M_replace_safe(this->size(), size_type(0), __str._M_data(), - __str.size()); - } - - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - append(const basic_string& __str, size_type __pos, size_type __n) - { - // Iff appending itself, string needs to pre-reserve the - // correct size so that _M_mutate does not clobber the - // pointer __str._M_data() formed here. - __str._M_check(__pos, "basic_string::append"); - __n = __str._M_limit(__pos, __n); - const size_type __len = __n + this->size(); - if (__len > this->capacity()) - this->reserve(__len); - return _M_replace_safe(this->size(), size_type(0), __str._M_data() - + __pos, __n); - } - - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - append(const _CharT* __s, size_type __n) - { - __glibcxx_requires_string_len(__s, __n); - const size_type __len = __n + this->size(); - if (__len > this->capacity()) - this->reserve(__len); - return _M_replace_safe(this->size(), size_type(0), __s, __n); - } - + template basic_string<_CharT, _Traits, _Alloc> operator+(const _CharT* __lhs, @@ -659,7 +626,7 @@ __n = _M_limit(__pos, __n); __glibcxx_requires_string_len(__s, __n); if (__n) - traits_type::copy(__s, _M_data() + __pos, __n); + _M_copy(__s, _M_data() + __pos, __n); // 21.3.5.7 par 3: do not append null. (good.) return __n; } diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/append/char/1.cc libstdc++-v3/testsuite/21_strings/basic_string/append/char/1.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/append/char/1.cc 2003-09-23 22:02:04.000000000 +0200 +++ libstdc++-v3/testsuite/21_strings/basic_string/append/char/1.cc 2004-10-23 02:19:29.000000000 +0200 @@ -18,7 +18,7 @@ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. -// 21.3.5.3 basic_string::assign +// 21.3.5.2 basic_string::append #include #include diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/append/char/2.cc libstdc++-v3/testsuite/21_strings/basic_string/append/char/2.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/append/char/2.cc 1970-01-01 01:00:00.000000000 +0100 +++ libstdc++-v3/testsuite/21_strings/basic_string/append/char/2.cc 2004-10-24 17:31:35.000000000 +0200 @@ -0,0 +1,67 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// append(const _CharT* __s, size_type __n) +// append(const _CharT* __s) +void +test02() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + string one; + string two; + string three; + const char * source = "Written in your eyes"; + + one.append(source); + VERIFY( one == "Written in your eyes" ); + + two.append(source, 20); + VERIFY( two == "Written in your eyes" ); + + three.append(source, 7); + VERIFY( three == "Written" ); + + three.clear(); + three.append(source + 8, 2); + VERIFY( three == "in" ); + + one.append(one.c_str(), 20); + VERIFY( one == "Written in your eyesWritten in your eyes" ); + + two.append(two.c_str() + 16, 4); + VERIFY( two == "Written in your eyeseyes" ); + + two.append(two.c_str(), 3); + VERIFY( two == "Written in your eyeseyesWri" ); +} + +int main() +{ + test02(); + return 0; +} diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/append/char/3.cc libstdc++-v3/testsuite/21_strings/basic_string/append/char/3.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/append/char/3.cc 1970-01-01 01:00:00.000000000 +0100 +++ libstdc++-v3/testsuite/21_strings/basic_string/append/char/3.cc 2004-10-25 10:20:56.000000000 +0200 @@ -0,0 +1,56 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// Upon reallocation (basic_string::reserve) we were copying from +// deallocated memory. +void +test03() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + const char * source = "Kesto"; + + for (unsigned i = 0; i < 10; ++i) + { + string one(source); + string two(source); + for (unsigned j = 0; j < 18; ++j) + { + VERIFY( one == two ); + one.append(one); + one += 'x'; + two.append(two.c_str(), two.size()); + two += 'x'; + } + } +} + +int main() +{ + test03(); + return 0; +} diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/append/wchar_t/1.cc libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/1.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/append/wchar_t/1.cc 2003-09-23 22:02:05.000000000 +0200 +++ libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/1.cc 2004-10-23 02:19:29.000000000 +0200 @@ -18,7 +18,7 @@ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. -// 21.3.5.3 basic_string::assign +// 21.3.5.2 basic_string::append #include #include diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/append/wchar_t/2.cc libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/2.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/append/wchar_t/2.cc 1970-01-01 01:00:00.000000000 +0100 +++ libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/2.cc 2004-10-24 17:31:51.000000000 +0200 @@ -0,0 +1,67 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// append(const _CharT* __s, size_type __n) +// append(const _CharT* __s) +void +test02() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + wstring one; + wstring two; + wstring three; + const wchar_t * source = L"Written in your eyes"; + + one.append(source); + VERIFY( one == L"Written in your eyes" ); + + two.append(source, 20); + VERIFY( two == L"Written in your eyes" ); + + three.append(source, 7); + VERIFY( three == L"Written" ); + + three.clear(); + three.append(source + 8, 2); + VERIFY( three == L"in" ); + + one.append(one.c_str(), 20); + VERIFY( one == L"Written in your eyesWritten in your eyes" ); + + two.append(two.c_str() + 16, 4); + VERIFY( two == L"Written in your eyeseyes" ); + + two.append(two.c_str(), 3); + VERIFY( two == L"Written in your eyeseyesWri" ); +} + +int main() +{ + test02(); + return 0; +} diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/append/wchar_t/3.cc libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/3.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/append/wchar_t/3.cc 1970-01-01 01:00:00.000000000 +0100 +++ libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/3.cc 2004-10-25 10:21:20.000000000 +0200 @@ -0,0 +1,56 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// Upon reallocation (basic_string::reserve) we were copying from +// deallocated memory. +void +test03() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + const wchar_t * source = L"Kesto"; + + for (unsigned i = 0; i < 10; ++i) + { + wstring one(source); + wstring two(source); + for (unsigned j = 0; j < 18; ++j) + { + VERIFY( one == two ); + one.append(one); + one += L'x'; + two.append(two.c_str(), two.size()); + two += L'x'; + } + } +} + +int main() +{ + test03(); + return 0; +} diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/assign/char/3.cc libstdc++-v3/testsuite/21_strings/basic_string/assign/char/3.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/assign/char/3.cc 2003-09-23 22:02:05.000000000 +0200 +++ libstdc++-v3/testsuite/21_strings/basic_string/assign/char/3.cc 2004-10-24 16:55:29.000000000 +0200 @@ -1,6 +1,6 @@ // 2001-10-30 Benjamin Kosnik -// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. // // 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 @@ -21,7 +21,6 @@ // 21.3.5 string modifiers #include -#include #include // assign(const _CharT* __s, size_type __n) @@ -35,7 +34,6 @@ string one; string two; - string three = two; const char * source = "Selling England by the pound"; one.assign(source); diff -urN libstdc++-v3-orig/testsuite/21_strings/basic_string/assign/wchar_t/3.cc libstdc++-v3/testsuite/21_strings/basic_string/assign/wchar_t/3.cc --- libstdc++-v3-orig/testsuite/21_strings/basic_string/assign/wchar_t/3.cc 2003-09-23 22:02:05.000000000 +0200 +++ libstdc++-v3/testsuite/21_strings/basic_string/assign/wchar_t/3.cc 2004-10-24 16:55:19.000000000 +0200 @@ -1,6 +1,6 @@ // 2001-10-30 Benjamin Kosnik -// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. // // 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 @@ -21,7 +21,6 @@ // 21.3.5 string modifiers #include -#include #include // assign(const _CharT* __s, size_type __n) @@ -35,7 +34,6 @@ wstring one; wstring two; - wstring three = two; const wchar_t* source = L"Selling England by the pound"; one.assign(source);