This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Fix libstdc++/40518


Hi,

tested x86_64-linux, committed to mainline.

Paolo.

///////////////////////////
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.
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 148848)
+++ include/bits/basic_string.h	(working copy)
@@ -197,12 +197,17 @@
 
 	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 @@
        *  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: include/bits/basic_string.tcc
===================================================================
--- include/bits/basic_string.tcc	(revision 148848)
+++ include/bits/basic_string.tcc	(working copy)
@@ -386,6 +386,29 @@
      }
 
    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,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]