diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 000430fadbe15bf76d7cf92d4768a9c6a0adcd9b..25857cbfa10f89cf6b44a85e24da035730a95b1d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2008-12-02  Paolo Carlini  <paolo.carlini@oracle.com>
+
+	PR libstdc++/38365 (cont)
+	* src/localename.cc (locale::locale(const locale&, const locale&,
+	category)): Revert last changes.
+	* src/localename.cc (locale::_Impl::_M_replace_categories(const
+	_Impl*, category)): Fix here instead; rework.
+
 2008-12-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
 	PR libstdc++/38365
diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc
index fe6204b9b4997d208753470f5060f7a3194d4ceb..5f5ec5f62e972c85e67b8ac3e3a3d99231e90122 100644
--- a/libstdc++-v3/src/localename.cc
+++ b/libstdc++-v3/src/localename.cc
@@ -157,14 +157,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   locale::locale(const locale& __base, const locale& __add, category __cat)
   : _M_impl(0)
-  {
-    _M_coalesce(__base, __add, __cat);
-    if (!__base._M_impl->_M_names[0] || !__add._M_impl->_M_names[0])
-      {
-	delete [] _M_impl->_M_names[0];
-	_M_impl->_M_names[0] = 0;   // Unnamed.
-      }
-  }
+  { _M_coalesce(__base, __add, __cat); }
 
   void
   locale::_M_coalesce(const locale& __base, const locale& __add, 
@@ -274,29 +267,43 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   _M_replace_categories(const _Impl* __imp, category __cat)
   {
     category __mask = 1;
-    const bool __have_names = _M_names[0] && __imp->_M_names[0];
-    for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
+    if (!_M_names[0] || !__imp->_M_names[0])
+      {
+	if (_M_names[0])
+	  {
+	    delete [] _M_names[0];
+	    _M_names[0] = 0;   // Unnamed.
+	  }
+
+	for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
+	  {
+	    if (__mask & __cat)
+	      // Need to replace entry in _M_facets with other locale's info.
+	      _M_replace_category(__imp, _S_facet_categories[__ix]);
+	  }
+      }
+    else
       {
-	if (__mask & __cat)
+	if (!_M_names[1])
 	  {
-	    // Need to replace entry in _M_facets with other locale's info.
-	    _M_replace_category(__imp, _S_facet_categories[__ix]);
-	    // If both have names, go ahead and mangle.
-	    if (__have_names)
+	    // A full set of _M_names must be prepared, all identical
+	    // to _M_names[0] to begin with. Then, below, a few will
+	    // be replaced by the corresponding __imp->_M_names. I.e.,
+	    // not a "simple" locale anymore (see locale::operator==).
+	    const size_t __len = std::strlen(_M_names[0]) + 1;
+	    for (size_t __i = 1; __i < _S_categories_size; ++__i)
 	      {
-		if (!_M_names[1])
-		  {
-		    // A full set of _M_names must be prepared, all identical
-		    // to _M_names[0] to begin with. Then, below, a few will
-		    // be replaced by the corresponding __imp->_M_names. I.e.,
-		    // not a "simple" locale anymore (see locale::operator==).
-		    const size_t __len = std::strlen(_M_names[0]) + 1;
-		    for (size_t __i = 1; __i < _S_categories_size; ++__i)
-		      {
-			_M_names[__i] = new char[__len];
-			std::memcpy(_M_names[__i], _M_names[0], __len);
-		      }
-		  }
+		_M_names[__i] = new char[__len];
+		std::memcpy(_M_names[__i], _M_names[0], __len);
+	      }
+	  }
+
+	for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
+	  {
+	    if (__mask & __cat)
+	      {
+		// Need to replace entry in _M_facets with other locale's info.
+		_M_replace_category(__imp, _S_facet_categories[__ix]);
 
 		// FIXME: Hack for libstdc++/29217: the numerical encodings
 		// of the time and collate categories are swapped vs the