OSDN Git Service

2009-06-23 Paolo Carlini <paolo.carlini@oracle.com>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Jun 2009 12:36:43 +0000 (12:36 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Jun 2009 12:36:43 +0000 (12:36 +0000)
PR libstdc++/40518
* include/bits/basic_string.h (basic_string<>::_Rep::
_M_set_length_and_sharable): Do not write the empty rep.
(basic_string<>::erase(iterator, iterator)): Likewise,
move out of line...
* include/bits/basic_string.tcc: ... here.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148850 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.tcc

index fc14048..a92920e 100644 (file)
@@ -1,3 +1,12 @@
+2009-06-23  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR libstdc++/40518
+       * include/bits/basic_string.h (basic_string<>::_Rep::
+       _M_set_length_and_sharable): Do not write the empty rep.
+       (basic_string<>::erase(iterator, iterator)): Likewise,
+       move out of line...
+       * include/bits/basic_string.tcc: ... here.
+
 2009-06-22  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * testsuite/util/testsuite_common_types.h (bitwise_operators,
index 1e8300d..085aea4 100644 (file)
@@ -197,12 +197,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
        void
        _M_set_length_and_sharable(size_type __n)
-       { 
-         this->_M_set_sharable();  // One reference.
-         this->_M_length = __n;
-         traits_type::assign(this->_M_refdata()[__n], _S_terminal);
-         // grrr. (per 21.3.4)
-         // You cannot leave those LWG people alone for a second.
+       {
+#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+         if (__builtin_expect(this != &_S_empty_rep(), false))
+#endif
+           {
+             this->_M_set_sharable();  // One reference.
+             this->_M_length = __n;
+             traits_type::assign(this->_M_refdata()[__n], _S_terminal);
+             // grrr. (per 21.3.4)
+             // You cannot leave those LWG people alone for a second.
+           }
        }
 
        _CharT*
@@ -1226,16 +1231,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        *  The value of the string doesn't change if an error is thrown.
       */
       iterator
-      erase(iterator __first, iterator __last)
-      {
-       _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
-                                && __last <= _M_iend());
-        const size_type __pos = __first - _M_ibegin();
-       _M_mutate(__pos, __last - __first, size_type(0));
-       _M_rep()->_M_set_leaked();
-       return iterator(_M_data() + __pos);
-      }
-
+      erase(iterator __first, iterator __last);
       /**
        *  @brief  Replace characters with value from another string.
        *  @param pos  Index of first character to replace.
index ec771c6..d450a47 100644 (file)
@@ -386,6 +386,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
      }
 
    template<typename _CharT, typename _Traits, typename _Alloc>
+     typename basic_string<_CharT, _Traits, _Alloc>::iterator
+     basic_string<_CharT, _Traits, _Alloc>::
+     erase(iterator __first, iterator __last)
+     {
+       _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
+                               && __last <= _M_iend());
+
+       // NB: This isn't just an optimization (bail out early when
+       // there is nothing to do, really), it's also a correctness
+       // issue vs MT, see libstdc++/40518.
+       const size_type __size = __last - __first;
+       if (__size)
+        {
+          const size_type __pos = __first - _M_ibegin();
+          _M_mutate(__pos, __size, size_type(0));
+          _M_rep()->_M_set_leaked();
+          return iterator(_M_data() + __pos);
+        }
+       else
+        return __first;
+     }
+
+   template<typename _CharT, typename _Traits, typename _Alloc>
      basic_string<_CharT, _Traits, _Alloc>&
      basic_string<_CharT, _Traits, _Alloc>::
      replace(size_type __pos, size_type __n1, const _CharT* __s,