diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0a779b6b25744adee4d281d91e222336f536dd25..ab1f558a0327092817956e905402ac18eee962ac 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2005-11-03  Paolo Carlini  <pcarlini@suse.de>
+
+	* include/ext/sso_string_base.h (__sso_string_base<>::_M_swap):
+	Change the various traits_type::copy call to always copy the
+	entire local buffer; return early and don't do a full swap on
+	the lengths for two common cases; change two _S_copy to plain
+	traits_type::copy.
+
 2005-11-02  Thomas Kho  <tkho@ucla.edu>
 
 	PR libstdc++/23425
diff --git a/libstdc++-v3/include/ext/sso_string_base.h b/libstdc++-v3/include/ext/sso_string_base.h
index f9b32330f62102cf59b0b259c98753dae9c8f2ef..c37bd88ca5a7eae07b9efd444181be5c4ce9723b 100644
--- a/libstdc++-v3/include/ext/sso_string_base.h
+++ b/libstdc++-v3/include/ext/sso_string_base.h
@@ -255,29 +255,34 @@ namespace __gnu_cxx
 	      {
 		_CharT __tmp_data[_S_local_capacity + 1];
 		traits_type::copy(__tmp_data, __rcs._M_local_data,
-				  __rcs._M_length() + 1);
+				  _S_local_capacity + 1);
 		traits_type::copy(__rcs._M_local_data, _M_local_data,
-				  _M_length() + 1);
+				  _S_local_capacity + 1);
 		traits_type::copy(_M_local_data, __tmp_data,
-				  __rcs._M_length() + 1);
+				  _S_local_capacity + 1);
 	      }
 	    else if (__rcs._M_length())
 	      {
 		traits_type::copy(_M_local_data, __rcs._M_local_data,
-				  __rcs._M_length() + 1);
-		traits_type::assign(__rcs._M_local_data[0], _CharT());
+				  _S_local_capacity + 1);
+		_M_length(__rcs._M_length());
+		__rcs._M_set_length(0);
+		return;
 	      }
 	    else if (_M_length())
 	      {
 		traits_type::copy(__rcs._M_local_data, _M_local_data,
-				  _M_length() + 1);
-		traits_type::assign(_M_local_data[0], _CharT());
+				  _S_local_capacity + 1);
+		__rcs._M_length(_M_length());
+		_M_set_length(0);
+		return;
 	      }
 	  }
 	else
 	  {
 	    const size_type __tmp_capacity = __rcs._M_allocated_capacity;
-	    _S_copy(__rcs._M_local_data, _M_local_data, _M_length() + 1);
+	    traits_type::copy(__rcs._M_local_data, _M_local_data,
+			      _S_local_capacity + 1);
 	    _M_data(__rcs._M_data());
 	    __rcs._M_data(__rcs._M_local_data);
 	    _M_capacity(__tmp_capacity);
@@ -287,8 +292,8 @@ namespace __gnu_cxx
 	  const size_type __tmp_capacity = _M_allocated_capacity;
 	  if (__rcs._M_is_local())
 	    {
-	      _S_copy(_M_local_data, __rcs._M_local_data,
-		      __rcs._M_length() + 1);
+	      traits_type::copy(_M_local_data, __rcs._M_local_data,
+				_S_local_capacity + 1);
 	      __rcs._M_data(_M_data());
 	      _M_data(_M_local_data);
 	    }