public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] sso-string@gnu-versioned-namespace [PR83077]
@ 2023-08-10  5:13 François Dumont
  2023-08-11  5:43 ` François Dumont
  0 siblings, 1 reply; 20+ messages in thread
From: François Dumont @ 2023-08-10  5:13 UTC (permalink / raw)
  To: libstdc++; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 10052 bytes --]

Hi

I've eventually completed this work.

This evolution will allow to build libstdc++ without dual abi and using 
cxx11 abi. For the moment such a config is only accessible through the 
--enable-symvers=gnu-versioned-namespace configuration.

     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

     Use cxx11 abi when activating versioned namespace mode.

     libstdcxx-v3/ChangeLog:

             PR libstdc++/83077
             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default 
to "new" libstdcxx abi.
             * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base
             members.
             * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
             * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
             * config/locale/gnu/numeric_members.cc
             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
             * configure: Regenerate.
             * include/bits/c++config
             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):
             Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):
             Likewise.
             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW
             basic_string as __std_cow_string for use in stdexcept.
             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.
             (__cow_string(const char*)): New.
             (__cow_string::c_str()): New.
             * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True
             when std::__8::basic_string type is found.
             * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
             * src/Makefile.in: Regenerate.
             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,
             cxx11-ios_failure.cc entries to...
             (sources): ...this.
             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
             cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
             cxx11-wlocale-inst.cc entries to...
             (inst_sources): ...this.
             * src/c++11/Makefile.in: Regenerate.
             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include <bits/cow_string.h>.
             [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
             <stdexcept>. Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string definition
             in <stdexcept> is skipped.
             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
locale-inst.cc.
             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cxx11-wlocale-inst.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
std::use_facet<num_put<>>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
std::has_facet<num_put<>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
istreambuf_iterator<C>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
ostreambuf_iterator<C>>): Instantiate.
             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
only when configured
             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
ostreambuf_iterator<C>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
ostreambuf_iterator<C>>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
mbstate_t>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
mbstate_t>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
mbstate_t>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
mbstate_t>>(const locale&)): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
mbstate_t>>(const locale&)): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
const C*,
             ios_base::fmtflags, bool)): Define.
             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
long, const C*,
             ios_base::fmtflags, bool)): Define.
             * src/c++11/string-inst.cc 
(_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following
             _GLIBCXX_USE_CXX11_ABI value.
             [_GLIBCXX_USE_CXX11_ABI && 
!_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. Include 
<bits/cow_string.h>.
             Define basic_string as __std_cow_string for the current 
translation unit.
             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip 
definitions.
             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, unique 
cow-istream-string.cc entry
             move to...
             (inst_sources): ...this.
             * src/c++98/Makefile.in: Regenerate.
             * src/c++98/cow-istream-string.cc: Include <bits/c++config.h>.
             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
definitions.
             * src/c++98/ios_failure.cc 
[_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
Build only when configured
             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
             * src/c++98/locale_facets.cc 
[_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
             * src/c++98/stdexcept.cc
             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
Remove.
             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
Remove.

Tested under linux x86_64 with following configs:

--enable-symvers=gnu-versioned-namespace

--disable-libstdcxx-dual-abi

Ok to commit ?

François



[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 57833 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b25378eaace..322f1e42611 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     AC_MSG_NOTICE([dual ABI is disabled])
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      AC_MSG_NOTICE([dual ABI is disabled])
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c4da56c3042..fd431f28547 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,13 +70702,18 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index dd47f274d5f..b90efc81d33 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index e5f094fd13e..d5b98d30a70 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,8 +32,6 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #ifdef __cpp_lib_is_constant_evaluated
@@ -44,6 +42,10 @@
 # define __cpp_lib_constexpr_string 201611L
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -835,6 +837,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -906,6 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -933,6 +937,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -969,7 +974,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { reserve(); }
 #pragma GCC diagnostic pop
 #endif
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -978,6 +983,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1026,6 +1032,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1035,6 +1042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1345,6 +1353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1489,6 +1498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2107,6 +2117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2178,6 +2189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2192,6 +2204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2249,6 +2262,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3054,6 +3068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3257,6 +3272,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3420,6 +3436,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3481,6 +3498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3506,6 +3524,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3629,6 +3648,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3642,6 +3662,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+  #endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3682,6 +3703,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3716,7 +3738,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // 21.3.5.7 par 3: do not append null.  (good.)
       return __n;
     }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..07e6c74e37f 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,9 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
 #if _GLIBCXX_USE_CXX11_ABI
+# if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,7 +64,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
+# endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
 
   typedef basic_string<char> __sso_string;
 #else // _GLIBCXX_USE_CXX11_ABI
@@ -95,7 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
   };
 #endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else  // ! _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   typedef basic_string<char> __sso_string;
   typedef basic_string<char> __cow_string;
 #endif
@@ -127,7 +131,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +237,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index b4c427d487c..a43bf105308 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -963,6 +963,8 @@ class StdStringPrinter:
     def __init__(self, typename, val):
         self.val = val
         self.new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self.new_string and _versioned_namespace:
+            self.new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 5b9af41cdb9..ec0c502ecb1 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -89,6 +89,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -102,6 +105,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index f42d957af36..c9c1b65db52 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -510,14 +509,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) $(experimen
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 682be1669a4..82227338798 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -40,15 +40,11 @@ ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -59,8 +55,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -77,19 +77,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -99,6 +91,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e7a09fe3246..2d94425480b 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,25 +122,26 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = chrono.lo codecvt.lo condition_variable.lo \
-	cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
-	functional.lo futex.lo future.lo hash_c++0x.lo \
+	cow-locale_init.lo cow-stdexcept.lo ctype.lo cxx11-hash_tr1.lo \
+	cxx11-ios_failure.lo cxx11-stdexcept.lo debug.lo \
+	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
 	hashtable_c++0x.lo ios.lo ios_errcat.lo mutex.lo random.lo \
 	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
 	thread.lo $(am__objects_2) $(am__objects_3)
-@ENABLE_DUAL_ABI_TRUE@am__objects_5 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_5 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_6 = $(am__objects_5) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -461,14 +462,10 @@ host_sources = \
 	ctype_configure_char.cc \
 	ctype_members.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -478,8 +475,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -496,19 +497,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -517,6 +510,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 85277763427..6833f903f47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -165,6 +162,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -190,6 +188,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..8d5eec814d2 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,53 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_CXX11_ABI
+# include <bits/cow_string.h>
+#endif
+
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+  typedef std::string cowstr;
+#else
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+#endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +156,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
 
   __cow_string::__cow_string() : _M_str() { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +180,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +192,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +210,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +499,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..38ab35692a3 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -76,3 +74,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..ea9dcf02639 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,12 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +66,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +87,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +136,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 284ffda3443..eb24325af67 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -90,13 +90,6 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
-
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
@@ -118,6 +111,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -142,7 +136,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index a100df77a6d..d2ed2a221f2 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,31 +121,30 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_5 = parallel_settings.lo
-am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \
-	$(am__objects_5)
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \
-	localename.lo math_stubs_float.lo math_stubs_long_double.lo \
-	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
-	streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \
-	$(am__objects_6)
+am__objects_4 = parallel_settings.lo
+am__objects_5 = basic_file.lo c++locale.lo $(am__objects_3) \
+	$(am__objects_4)
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_init.lo locale_facets.lo localename.lo \
+	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
+	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
+	valarray.lo $(am__objects_2) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -471,10 +470,6 @@ host_sources_extra = \
 	basic_file.cc c++locale.cc \
 	${inst_sources} ${parallel_sources}
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -494,6 +489,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -518,7 +514,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
+
+# ifdef _GLIBCXX_USE_NLS
+#  include <libintl.h>
+#  define _(msgid)   gettext (msgid)
+# else
+#  define _(msgid)   (msgid)
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-10  5:13 [PATCH] sso-string@gnu-versioned-namespace [PR83077] François Dumont
@ 2023-08-11  5:43 ` François Dumont
  2023-08-11  7:51   ` Jonathan Wakely
  0 siblings, 1 reply; 20+ messages in thread
From: François Dumont @ 2023-08-11  5:43 UTC (permalink / raw)
  To: libstdc++; +Cc: gcc-patches

I hadn't tested the most basic default configuration and it is failing, 
I need some more time yet.

François


On 10/08/2023 07:13, François Dumont wrote:
> Hi
>
> I've eventually completed this work.
>
> This evolution will allow to build libstdc++ without dual abi and 
> using cxx11 abi. For the moment such a config is only accessible 
> through the --enable-symvers=gnu-versioned-namespace configuration.
>
>     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>
>     Use cxx11 abi when activating versioned namespace mode.
>
>     libstdcxx-v3/ChangeLog:
>
>             PR libstdc++/83077
>             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
> Default to "new" libstdcxx abi.
>             * config/locale/dragonfly/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>             members.
>             * config/locale/generic/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>             * config/locale/gnu/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>             * config/locale/gnu/numeric_members.cc
>             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>             * configure: Regenerate.
>             * include/bits/c++config
>             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
> _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>             Define empty.
> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
> _GLIBCXX_DEFAULT_ABI_TAG):
>             Likewise.
>             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
> Define a light version of COW
>             basic_string as __std_cow_string for use in stdexcept.
>             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
> __cow_string.
>             (__cow_string(const char*)): New.
>             (__cow_string::c_str()): New.
>             * python/libstdcxx/v6/printers.py 
> (StdStringPrinter::__init__): Set self.new_string to True
>             when std::__8::basic_string type is found.
>             * src/Makefile.am 
> [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
>             * src/Makefile.in: Regenerate.
>             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
> cxx11-hash_tr1.cc,
>             cxx11-ios_failure.cc entries to...
>             (sources): ...this.
>             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
> cow-sstream-inst.cc, cow-string-inst.cc,
>             cow-string-io-inst.cc, cow-wtring-inst.cc, 
> cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>             cxx11-wlocale-inst.cc entries to...
>             (inst_sources): ...this.
>             * src/c++11/Makefile.in: Regenerate.
>             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Include <bits/cow_string.h>.
>             [_GLIBCXX_USE_DUAL_ABI || 
> _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
>             <stdexcept>. Define 
> _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string definition
>             in <stdexcept> is skipped.
>             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
> definitions.
>             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-string-io-inst.cc 
> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-wstring-io-inst.cc 
> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cxx11-ios_failure.cc 
> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
> locale-inst.cc.
>             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cxx11-wlocale-inst.cc 
> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/locale-inst-numeric.h
> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
> std::use_facet<num_put<>>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
> std::has_facet<num_put<>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
> istreambuf_iterator<C>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
> ostreambuf_iterator<C>>): Instantiate.
>             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
> only when configured
>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
> ostreambuf_iterator<C>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
> ostreambuf_iterator<C>>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
> mbstate_t>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
> mbstate_t>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
> mbstate_t>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
> mbstate_t>>(const locale&)): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
> mbstate_t>>(const locale&)): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
> const C*,
>             ios_base::fmtflags, bool)): Define.
>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
> long, const C*,
>             ios_base::fmtflags, bool)): Define.
>             * src/c++11/string-inst.cc 
> (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following
>             _GLIBCXX_USE_CXX11_ABI value.
>             [_GLIBCXX_USE_CXX11_ABI && 
> !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
> Include <bits/cow_string.h>.
>             Define basic_string as __std_cow_string for the current 
> translation unit.
>             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, 
> unique cow-istream-string.cc entry
>             move to...
>             (inst_sources): ...this.
>             * src/c++98/Makefile.in: Regenerate.
>             * src/c++98/cow-istream-string.cc: Include 
> <bits/c++config.h>.
>             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
> definitions.
>             * src/c++98/ios_failure.cc 
> [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
> Build only when configured
>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>             * src/c++98/locale_facets.cc 
> [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>             * src/c++98/stdexcept.cc
>             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
> Remove.
>
> Tested under linux x86_64 with following configs:
>
> --enable-symvers=gnu-versioned-namespace
>
> --disable-libstdcxx-dual-abi
>
> Ok to commit ?
>
> François
>
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-11  5:43 ` François Dumont
@ 2023-08-11  7:51   ` Jonathan Wakely
  2023-08-13 13:27     ` François Dumont
  0 siblings, 1 reply; 20+ messages in thread
From: Jonathan Wakely @ 2023-08-11  7:51 UTC (permalink / raw)
  To: François Dumont; +Cc: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 10383 bytes --]

On Fri, 11 Aug 2023, 06:44 François Dumont via Libstdc++, <
libstdc++@gcc.gnu.org> wrote:

> I hadn't tested the most basic default configuration and it is failing,


I did wonder about that when you said which configurations you had tested :)




> I need some more time yet.
>

OK, no problem.

I actually have an idea for replacing the __cow_string hack with something
better, which I will try to work on next week. That might make things
simpler for you, as you won't need the __std_cow_string macro.





> François
>
>
> On 10/08/2023 07:13, François Dumont wrote:
> > Hi
> >
> > I've eventually completed this work.
> >
> > This evolution will allow to build libstdc++ without dual abi and
> > using cxx11 abi. For the moment such a config is only accessible
> > through the --enable-symvers=gnu-versioned-namespace configuration.
> >
> >     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
> >
> >     Use cxx11 abi when activating versioned namespace mode.
> >
> >     libstdcxx-v3/ChangeLog:
> >
> >             PR libstdc++/83077
> >             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]:
> > Default to "new" libstdcxx abi.
> >             * config/locale/dragonfly/monetary_members.cc
> > [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
> >             members.
> >             * config/locale/generic/monetary_members.cc
> > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
> >             * config/locale/gnu/monetary_members.cc
> > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
> >             * config/locale/gnu/numeric_members.cc
> >             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
> >             * configure: Regenerate.
> >             * include/bits/c++config
> >             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11,
> > _GLIBCXX_BEGIN_NAMESPACE_CXX11):
> >             Define empty.
> > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11,
> > _GLIBCXX_DEFAULT_ABI_TAG):
> >             Likewise.
> >             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]:
> > Define a light version of COW
> >             basic_string as __std_cow_string for use in stdexcept.
> >             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define
> > __cow_string.
> >             (__cow_string(const char*)): New.
> >             (__cow_string::c_str()): New.
> >             * python/libstdcxx/v6/printers.py
> > (StdStringPrinter::__init__): Set self.new_string to True
> >             when std::__8::basic_string type is found.
> >             * src/Makefile.am
> > [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
> >             * src/Makefile.in: Regenerate.
> >             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
> >             (dual_abi_sources): ...this. Also move cow-local_init.cc,
> > cxx11-hash_tr1.cc,
> >             cxx11-ios_failure.cc entries to...
> >             (sources): ...this.
> >             (extra_string_inst_sources): Move cow-fstream-inst.cc,
> > cow-sstream-inst.cc, cow-string-inst.cc,
> >             cow-string-io-inst.cc, cow-wtring-inst.cc,
> > cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
> >             cxx11-wlocale-inst.cc entries to...
> >             (inst_sources): ...this.
> >             * src/c++11/Makefile.in: Regenerate.
> >             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]:
> > Include <bits/cow_string.h>.
> >             [_GLIBCXX_USE_DUAL_ABI ||
> > _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
> >             <stdexcept>. Define
> > _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string definition
> >             in <stdexcept> is skipped.
> >             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS
> > definitions.
> >             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++11/cow-string-io-inst.cc
> > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
> >             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++11/cow-wstring-io-inst.cc
> > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
> >             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++11/cxx11-ios_failure.cc
> > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
> >             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
> >             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include
> > locale-inst.cc.
> >             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++11/cxx11-wlocale-inst.cc
> > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
> >             * src/c++11/locale-inst-numeric.h
> > [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>,
> > std::use_facet<num_put<>>): Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>,
> > std::has_facet<num_put<>>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C,
> > istreambuf_iterator<C>>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C,
> > ostreambuf_iterator<C>>): Instantiate.
> >             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build
> > only when configured
> >             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
> >             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>):
> > Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>):
> > Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](time_put<C,
> > ostreambuf_iterator<C>>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C,
> > ostreambuf_iterator<C>>): Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char,
> > mbstate_t>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
> > mbstate_t>): Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
> > mbstate_t>): Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)):
> > Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char,
> > mbstate_t>>(const locale&)): Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)):
> > Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)):
> > Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)):
> > Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char,
> > mbstate_t>>(const locale&)): Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)):
> > Instantiate.
> > [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)):
> > Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
> >             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>):
> > Instantiate.
> >             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long,
> > const C*,
> >             ios_base::fmtflags, bool)): Define.
> >             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long
> > long, const C*,
> >             ios_base::fmtflags, bool)): Define.
> >             * src/c++11/string-inst.cc
> > (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following
> >             _GLIBCXX_USE_CXX11_ABI value.
> >             [_GLIBCXX_USE_CXX11_ABI &&
> > !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
> >             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS.
> > Include <bits/cow_string.h>.
> >             Define basic_string as __std_cow_string for the current
> > translation unit.
> >             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]:
> > Skip definitions.
> >             * src/c++98/Makefile.am (cxx11_abi_sources): Remove,
> > unique cow-istream-string.cc entry
> >             move to...
> >             (inst_sources): ...this.
> >             * src/c++98/Makefile.in: Regenerate.
> >             * src/c++98/cow-istream-string.cc: Include
> > <bits/c++config.h>.
> >             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
> >             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip
> > definitions.
> >             * src/c++98/ios_failure.cc
> > [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
> >             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]:
> > Build only when configured
> >             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
> >             * src/c++98/locale_facets.cc
> > [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
> >             * src/c++98/stdexcept.cc
> >             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&):
> > Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&):
> > Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&):
> > Remove.
> >             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&):
> > Remove.
> >
> > Tested under linux x86_64 with following configs:
> >
> > --enable-symvers=gnu-versioned-namespace
> >
> > --disable-libstdcxx-dual-abi
> >
> > Ok to commit ?
> >
> > François
> >
> >
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-11  7:51   ` Jonathan Wakely
@ 2023-08-13 13:27     ` François Dumont
  2023-08-13 19:51       ` François Dumont
  2023-08-17 17:22       ` Jonathan Wakely
  0 siblings, 2 replies; 20+ messages in thread
From: François Dumont @ 2023-08-13 13:27 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches


[-- Attachment #1.1: Type: text/plain, Size: 22580 bytes --]

Here is the fixed patch tested in all 3 modes:

- _GLIBCXX_USE_DUAL_ABI

- !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI

- !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI

I don't know what you have in mind for the change below but I wanted to 
let you know that I tried to put COW std::basic_string into a nested 
__cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on 
string-inst.cc so I preferred the macro substitution approach.

There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
unrelated with my changes. I'll propose fixes in coming days.

     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

     Use cxx11 abi when activating versioned namespace mode. To do support
     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
_GLIBCXX_USE_CXX11_ABI.

     The main change is that std::__cow_string is now defined whenever 
_GLIBCXX_USE_DUAL_ABI
     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
available std::string in
     case of dual abi and a subset of it when it's not.

     On the other side std::__sso_string is defined only when 
_GLIBCXX_USE_DUAL_ABI is true
     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that std::__sso_string 
is a typedef for the
     cow std::string implementation when dual abi is disabled and cow 
string is being used.

     libstdcxx-v3/ChangeLog:

             PR libstdc++/83077
             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default 
to "new" libstdcxx abi.
             * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base
             members.
             * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
             * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
             * config/locale/gnu/numeric_members.cc
             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
             * configure: Regenerate.
             * include/bits/c++config
             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):
             Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):
             Likewise.
             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW
             basic_string as __std_cow_string for use in stdexcept.
             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.
             (__cow_string(const char*)): New.
             (__cow_string::c_str()): New.
             * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True
             when std::__8::basic_string type is found.
             * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
             * src/Makefile.in: Regenerate.
             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,
             cxx11-ios_failure.cc entries to...
             (sources): ...this.
             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
             cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
             cxx11-wlocale-inst.cc entries to...
             (inst_sources): ...this.
             * src/c++11/Makefile.in: Regenerate.
             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include <bits/cow_string.h>.
             [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
             including <stdexcept>. Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
             __cow_string definition in <stdexcept> is skipped.
             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
             Move static_assert to check std::_cow_string abi layout to...
             * src/c++11/string-inst.cc: ...here.
             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
following _GLIBCXX_USE_CXX11_ABI
             value.
             [_GLIBCXX_USE_CXX11_ABI && 
!_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. Include 
<bits/cow_string.h>.
             Define basic_string as __std_cow_string for the current 
translation unit.
             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
locale-inst.cc.
             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cxx11-wlocale-inst.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
std::use_facet<num_put<>>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
std::has_facet<num_put<>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
istreambuf_iterator<C>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
ostreambuf_iterator<C>>): Instantiate.
             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
only when configured
             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
ostreambuf_iterator<C>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
ostreambuf_iterator<C>>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
mbstate_t>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
mbstate_t>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
mbstate_t>>(const locale&)): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
mbstate_t>>(const locale&)): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
const C*,
             ios_base::fmtflags, bool)): Define.
             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
long, const C*,
             ios_base::fmtflags, bool)): Define.
             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip 
definitions.
             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, unique 
cow-istream-string.cc entry
             move to...
             (inst_sources): ...this.
             * src/c++98/Makefile.in: Regenerate.
             * src/c++98/cow-istream-string.cc: Include <bits/c++config.h>.
             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
definitions.
             * src/c++98/ios_failure.cc 
[_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
Build only when configured
             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
             * src/c++98/locale_facets.cc 
[_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
             * src/c++98/stdexcept.cc
             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
Remove.
             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
Remove.

Ok to commit ?

François

On 11/08/2023 09:51, Jonathan Wakely wrote:
>
>
> On Fri, 11 Aug 2023, 06:44 François Dumont via Libstdc++, 
> <libstdc++@gcc.gnu.org <mailto:libstdc%2B%2B@gcc.gnu.org>> wrote:
>
>     I hadn't tested the most basic default configuration and it is
>     failing,
>
>
> I did wonder about that when you said which configurations you had 
> tested :)
>
>
>
>
>     I need some more time yet.
>
>
> OK, no problem.
>
> I actually have an idea for replacing the __cow_string hack with 
> something better, which I will try to work on next week. That might 
> make things simpler for you, as you won't need the __std_cow_string macro.
>
>
>
>
>
>     François
>
>
>     On 10/08/2023 07:13, François Dumont wrote:
>     > Hi
>     >
>     > I've eventually completed this work.
>     >
>     > This evolution will allow to build libstdc++ without dual abi and
>     > using cxx11 abi. For the moment such a config is only accessible
>     > through the --enable-symvers=gnu-versioned-namespace configuration.
>     >
>     >     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>     >
>     >     Use cxx11 abi when activating versioned namespace mode.
>     >
>     >     libstdcxx-v3/ChangeLog:
>     >
>     >             PR libstdc++/83077
>     >             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]:
>     > Default to "new" libstdcxx abi.
>     >             * config/locale/dragonfly/monetary_members.cc
>     > [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>     >             members.
>     >             * config/locale/generic/monetary_members.cc
>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>     >             * config/locale/gnu/monetary_members.cc
>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>     >             * config/locale/gnu/numeric_members.cc
>     > [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>     >             * configure: Regenerate.
>     >             * include/bits/c++config
>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11,
>     > _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>     >             Define empty.
>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11,
>     > _GLIBCXX_DEFAULT_ABI_TAG):
>     >             Likewise.
>     >             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]:
>     > Define a light version of COW
>     >             basic_string as __std_cow_string for use in stdexcept.
>     >             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]:
>     Define
>     > __cow_string.
>     >             (__cow_string(const char*)): New.
>     >             (__cow_string::c_str()): New.
>     >             * python/libstdcxx/v6/printers.py
>     > (StdStringPrinter::__init__): Set self.new_string to True
>     >             when std::__8::basic_string type is found.
>     >             * src/Makefile.am
>     > [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources):
>     Define empty.
>     >             * src/Makefile.in: Regenerate.
>     >             * src/c++11/Makefile.am (cxx11_abi_sources): Rename
>     into...
>     >             (dual_abi_sources): ...this. Also move
>     cow-local_init.cc,
>     > cxx11-hash_tr1.cc,
>     >             cxx11-ios_failure.cc entries to...
>     >             (sources): ...this.
>     >             (extra_string_inst_sources): Move cow-fstream-inst.cc,
>     > cow-sstream-inst.cc, cow-string-inst.cc,
>     >             cow-string-io-inst.cc, cow-wtring-inst.cc,
>     > cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>     >             cxx11-wlocale-inst.cc entries to...
>     >             (inst_sources): ...this.
>     >             * src/c++11/Makefile.in: Regenerate.
>     >             * src/c++11/cow-fstream-inst.cc
>     [_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++11/cow-locale_init.cc
>     [_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++11/cow-sstream-inst.cc
>     [_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]:
>     > Include <bits/cow_string.h>.
>     >             [_GLIBCXX_USE_DUAL_ABI ||
>     > _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
>     >             <stdexcept>. Define
>     > _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string
>     definition
>     >             in <stdexcept> is skipped.
>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS
>     > definitions.
>     >             * src/c++11/cow-string-inst.cc
>     [_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++11/cow-string-io-inst.cc
>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>     >             * src/c++11/cow-wstring-inst.cc
>     [_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++11/cow-wstring-io-inst.cc
>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>     >             * src/c++11/cxx11-hash_tr1.cc
>     [!_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++11/cxx11-ios_failure.cc
>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>     >             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>     >             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include
>     > locale-inst.cc.
>     >             * src/c++11/cxx11-stdexcept.cc
>     [!_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++11/cxx11-wlocale-inst.cc
>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>     >             * src/c++11/locale-inst-numeric.h
>     > [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>,
>     > std::use_facet<num_put<>>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>,
>     > std::has_facet<num_put<>>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C,
>     > istreambuf_iterator<C>>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C,
>     > ostreambuf_iterator<C>>): Instantiate.
>     >             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]:
>     Build
>     > only when configured
>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>     >             [!_GLIBCXX_USE_DUAL_ABI](time_put<C,
>     > ostreambuf_iterator<C>>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C,
>     > ostreambuf_iterator<C>>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char,
>     > mbstate_t>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>     > mbstate_t>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>     > mbstate_t>): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char,
>     > mbstate_t>>(const locale&)): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char,
>     > mbstate_t>>(const locale&)): Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>     >             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>):
>     > Instantiate.
>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long,
>     > const C*,
>     >             ios_base::fmtflags, bool)): Define.
>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long
>     > long, const C*,
>     >             ios_base::fmtflags, bool)): Define.
>     >             * src/c++11/string-inst.cc
>     > (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following
>     >             _GLIBCXX_USE_CXX11_ABI value.
>     >             [_GLIBCXX_USE_CXX11_ABI &&
>     > !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>     >             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS.
>     > Include <bits/cow_string.h>.
>     >             Define basic_string as __std_cow_string for the current
>     > translation unit.
>     >             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]:
>     > Skip definitions.
>     >             * src/c++98/Makefile.am (cxx11_abi_sources): Remove,
>     > unique cow-istream-string.cc entry
>     >             move to...
>     >             (inst_sources): ...this.
>     >             * src/c++98/Makefile.in: Regenerate.
>     >             * src/c++98/cow-istream-string.cc: Include
>     > <bits/c++config.h>.
>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>     >             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip
>     > definitions.
>     >             * src/c++98/ios_failure.cc
>     > [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>     >             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]:
>     > Build only when configured
>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>     >             * src/c++98/locale_facets.cc
>     > [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>     >             * src/c++98/stdexcept.cc
>     > [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&):
>     > Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&):
>     > Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&):
>     > Remove.
>     > [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&):
>     > Remove.
>     >
>     > Tested under linux x86_64 with following configs:
>     >
>     > --enable-symvers=gnu-versioned-namespace
>     >
>     > --disable-libstdcxx-dual-abi
>     >
>     > Ok to commit ?
>     >
>     > François
>     >
>     >
>

[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 58660 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b25378eaace..322f1e42611 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     AC_MSG_NOTICE([dual ABI is disabled])
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      AC_MSG_NOTICE([dual ABI is disabled])
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c4da56c3042..fd431f28547 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,13 +70702,18 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index dd47f274d5f..b90efc81d33 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index e5f094fd13e..d5b98d30a70 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,8 +32,6 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #ifdef __cpp_lib_is_constant_evaluated
@@ -44,6 +42,10 @@
 # define __cpp_lib_constexpr_string 201611L
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -835,6 +837,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -906,6 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -933,6 +937,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -969,7 +974,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { reserve(); }
 #pragma GCC diagnostic pop
 #endif
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -978,6 +983,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1026,6 +1032,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1035,6 +1042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1345,6 +1353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1489,6 +1498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2107,6 +2117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2178,6 +2189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2192,6 +2204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2249,6 +2262,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3054,6 +3068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3257,6 +3272,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3420,6 +3436,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3481,6 +3498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3506,6 +3524,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3629,6 +3648,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3642,6 +3662,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+  #endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3682,6 +3703,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3716,7 +3738,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // 21.3.5.7 par 3: do not append null.  (good.)
       return __n;
     }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..33306508695 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,12 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
-
-  typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
+#endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
+#else
   typedef basic_string<char> __cow_string;
+#endif
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   // Emulates a new SSO string when the old std::string is in use.
   struct __sso_string
   {
@@ -94,10 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __sso_string& operator=(__sso_string&&) noexcept;
 #endif
   };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else
   typedef basic_string<char> __sso_string;
-  typedef basic_string<char> __cow_string;
 #endif
 
   /**
@@ -127,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index b4c427d487c..a43bf105308 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -963,6 +963,8 @@ class StdStringPrinter:
     def __init__(self, typename, val):
         self.val = val
         self.new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self.new_string and _versioned_namespace:
+            self.new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 5b9af41cdb9..ec0c502ecb1 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -89,6 +89,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -102,6 +105,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index f42d957af36..c9c1b65db52 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -510,14 +509,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) $(experimen
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 682be1669a4..82227338798 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -40,15 +40,11 @@ ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -59,8 +55,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -77,19 +77,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -99,6 +91,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e7a09fe3246..2d94425480b 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,25 +122,26 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = chrono.lo codecvt.lo condition_variable.lo \
-	cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
-	functional.lo futex.lo future.lo hash_c++0x.lo \
+	cow-locale_init.lo cow-stdexcept.lo ctype.lo cxx11-hash_tr1.lo \
+	cxx11-ios_failure.lo cxx11-stdexcept.lo debug.lo \
+	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
 	hashtable_c++0x.lo ios.lo ios_errcat.lo mutex.lo random.lo \
 	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
 	thread.lo $(am__objects_2) $(am__objects_3)
-@ENABLE_DUAL_ABI_TRUE@am__objects_5 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_5 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_6 = $(am__objects_5) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -461,14 +462,10 @@ host_sources = \
 	ctype_configure_char.cc \
 	ctype_members.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -478,8 +475,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -496,19 +497,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -517,6 +510,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 85277763427..6833f903f47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -165,6 +162,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -190,6 +188,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..06b314c2cf0 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,52 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_DUAL_ABI || (! _GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI)
+# if _GLIBCXX_USE_CXX11_ABI
+#  include <bits/cow_string.h>
+# endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+# if ! _GLIBCXX_USE_CXX11_ABI
+  typedef std::string cowstr;
+# else
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+# endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +155,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
-
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string() : _M_str() { }
 
+#if !_GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +190,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +497,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..25236a79950 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -70,9 +68,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
 
+#if _GLIBCXX_USE_DUAL_ABI
   // Converting constructor from ABI-tagged std::string to COW string.
   __cow_string::__cow_string(const string& s)
   : __cow_string(s.c_str(), s.length()) { }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..3cb4c70ca13 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,21 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
+#include <stdexcept>
+
+static_assert(sizeof(std::__cow_string) == sizeof(std::string),
+	      "sizeof(std::string) has changed");
+static_assert(alignof(std::__cow_string) == alignof(std::string),
+	      "alignof(std::string) has changed");
+#endif
+
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +75,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +114,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +145,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 284ffda3443..eb24325af67 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -90,13 +90,6 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
-
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
@@ -118,6 +111,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -142,7 +136,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index a100df77a6d..d2ed2a221f2 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,31 +121,30 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_5 = parallel_settings.lo
-am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \
-	$(am__objects_5)
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \
-	localename.lo math_stubs_float.lo math_stubs_long_double.lo \
-	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
-	streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \
-	$(am__objects_6)
+am__objects_4 = parallel_settings.lo
+am__objects_5 = basic_file.lo c++locale.lo $(am__objects_3) \
+	$(am__objects_4)
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_init.lo locale_facets.lo localename.lo \
+	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
+	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
+	valarray.lo $(am__objects_2) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -471,10 +470,6 @@ host_sources_extra = \
 	basic_file.cc c++locale.cc \
 	${inst_sources} ${parallel_sources}
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -494,6 +489,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -518,7 +514,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
+
+# ifdef _GLIBCXX_USE_NLS
+#  include <libintl.h>
+#  define _(msgid)   gettext (msgid)
+# else
+#  define _(msgid)   (msgid)
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-13 13:27     ` François Dumont
@ 2023-08-13 19:51       ` François Dumont
  2023-08-17 17:17         ` François Dumont
  2023-08-17 17:22       ` Jonathan Wakely
  1 sibling, 1 reply; 20+ messages in thread
From: François Dumont @ 2023-08-13 19:51 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches


[-- Attachment #1.1: Type: text/plain, Size: 23415 bytes --]

Here is another version with enhanced sizeof/alignof static_assert in 
string-inst.cc for the std::__cow_string definition from <stdexcept>. 
The assertions in cow-stdexcept.cc are now checking the definition which 
is in the same file.

On 13/08/2023 15:27, François Dumont wrote:
>
> Here is the fixed patch tested in all 3 modes:
>
> - _GLIBCXX_USE_DUAL_ABI
>
> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>
> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>
> I don't know what you have in mind for the change below but I wanted 
> to let you know that I tried to put COW std::basic_string into a 
> nested __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more 
> impact on string-inst.cc so I preferred the macro substitution approach.
>
> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
> unrelated with my changes. I'll propose fixes in coming days.
>
>     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>
>     Use cxx11 abi when activating versioned namespace mode. To do support
>     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
> _GLIBCXX_USE_CXX11_ABI.
>
>     The main change is that std::__cow_string is now defined whenever 
> _GLIBCXX_USE_DUAL_ABI
>     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
> available std::string in
>     case of dual abi and a subset of it when it's not.
>
>     On the other side std::__sso_string is defined only when 
> _GLIBCXX_USE_DUAL_ABI is true
>     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
> std::__sso_string is a typedef for the
>     cow std::string implementation when dual abi is disabled and cow 
> string is being used.
>
>     libstdcxx-v3/ChangeLog:
>
>             PR libstdc++/83077
>             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
> Default to "new" libstdcxx abi.
>             * config/locale/dragonfly/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>             members.
>             * config/locale/generic/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>             * config/locale/gnu/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>             * config/locale/gnu/numeric_members.cc
>             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>             * configure: Regenerate.
>             * include/bits/c++config
>             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
> _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>             Define empty.
> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
> _GLIBCXX_DEFAULT_ABI_TAG):
>             Likewise.
>             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
> Define a light version of COW
>             basic_string as __std_cow_string for use in stdexcept.
>             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
> __cow_string.
>             (__cow_string(const char*)): New.
>             (__cow_string::c_str()): New.
>             * python/libstdcxx/v6/printers.py 
> (StdStringPrinter::__init__): Set self.new_string to True
>             when std::__8::basic_string type is found.
>             * src/Makefile.am 
> [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
>             * src/Makefile.in: Regenerate.
>             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
> cxx11-hash_tr1.cc,
>             cxx11-ios_failure.cc entries to...
>             (sources): ...this.
>             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
> cow-sstream-inst.cc, cow-string-inst.cc,
>             cow-string-io-inst.cc, cow-wtring-inst.cc, 
> cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>             cxx11-wlocale-inst.cc entries to...
>             (inst_sources): ...this.
>             * src/c++11/Makefile.in: Regenerate.
>             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Include <bits/cow_string.h>.
>             [_GLIBCXX_USE_DUAL_ABI || 
> _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>             including <stdexcept>. Define 
> _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>             __cow_string definition in <stdexcept> is skipped.
>             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
> definitions.
>             Move static_assert to check std::_cow_string abi layout to...
>             * src/c++11/string-inst.cc: ...here.
>             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
> following _GLIBCXX_USE_CXX11_ABI
>             value.
>             [_GLIBCXX_USE_CXX11_ABI && 
> !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
> Include <bits/cow_string.h>.
>             Define basic_string as __std_cow_string for the current 
> translation unit.
>             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-string-io-inst.cc 
> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-wstring-io-inst.cc 
> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cxx11-ios_failure.cc 
> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
> locale-inst.cc.
>             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cxx11-wlocale-inst.cc 
> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/locale-inst-numeric.h
> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
> std::use_facet<num_put<>>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
> std::has_facet<num_put<>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
> istreambuf_iterator<C>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
> ostreambuf_iterator<C>>): Instantiate.
>             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
> only when configured
>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
> ostreambuf_iterator<C>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
> ostreambuf_iterator<C>>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, mbstate_t>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
> mbstate_t>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
> mbstate_t>>(const locale&)): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
> mbstate_t>>(const locale&)): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
> const C*,
>             ios_base::fmtflags, bool)): Define.
>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
> long, const C*,
>             ios_base::fmtflags, bool)): Define.
>             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, 
> unique cow-istream-string.cc entry
>             move to...
>             (inst_sources): ...this.
>             * src/c++98/Makefile.in: Regenerate.
>             * src/c++98/cow-istream-string.cc: Include <bits/c++config.h>.
>             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
> definitions.
>             * src/c++98/ios_failure.cc 
> [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
> Build only when configured
>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>             * src/c++98/locale_facets.cc 
> [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>             * src/c++98/stdexcept.cc
>             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
> Remove.
>
> Ok to commit ?
>
> François
>
> On 11/08/2023 09:51, Jonathan Wakely wrote:
>>
>>
>> On Fri, 11 Aug 2023, 06:44 François Dumont via Libstdc++, 
>> <libstdc++@gcc.gnu.org <mailto:libstdc%2B%2B@gcc.gnu.org>> wrote:
>>
>>     I hadn't tested the most basic default configuration and it is
>>     failing,
>>
>>
>> I did wonder about that when you said which configurations you had 
>> tested :)
>>
>>
>>
>>
>>     I need some more time yet.
>>
>>
>> OK, no problem.
>>
>> I actually have an idea for replacing the __cow_string hack with 
>> something better, which I will try to work on next week. That might 
>> make things simpler for you, as you won't need the __std_cow_string 
>> macro.
>>
>>
>>
>>
>>
>>     François
>>
>>
>>     On 10/08/2023 07:13, François Dumont wrote:
>>     > Hi
>>     >
>>     > I've eventually completed this work.
>>     >
>>     > This evolution will allow to build libstdc++ without dual abi and
>>     > using cxx11 abi. For the moment such a config is only accessible
>>     > through the --enable-symvers=gnu-versioned-namespace configuration.
>>     >
>>     >     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>     >
>>     >     Use cxx11 abi when activating versioned namespace mode.
>>     >
>>     >     libstdcxx-v3/ChangeLog:
>>     >
>>     >             PR libstdc++/83077
>>     >             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]:
>>     > Default to "new" libstdcxx abi.
>>     >             * config/locale/dragonfly/monetary_members.cc
>>     > [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>     >             members.
>>     >             * config/locale/generic/monetary_members.cc
>>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>     >             * config/locale/gnu/monetary_members.cc
>>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>     >             * config/locale/gnu/numeric_members.cc
>>     > [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>     >             * configure: Regenerate.
>>     >             * include/bits/c++config
>>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11,
>>     > _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>     >             Define empty.
>>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11,
>>     > _GLIBCXX_DEFAULT_ABI_TAG):
>>     >             Likewise.
>>     >             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]:
>>     > Define a light version of COW
>>     >             basic_string as __std_cow_string for use in stdexcept.
>>     >             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]:
>>     Define
>>     > __cow_string.
>>     >             (__cow_string(const char*)): New.
>>     >             (__cow_string::c_str()): New.
>>     >             * python/libstdcxx/v6/printers.py
>>     > (StdStringPrinter::__init__): Set self.new_string to True
>>     >             when std::__8::basic_string type is found.
>>     >             * src/Makefile.am
>>     > [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources):
>>     Define empty.
>>     >             * src/Makefile.in: Regenerate.
>>     >             * src/c++11/Makefile.am (cxx11_abi_sources): Rename
>>     into...
>>     >             (dual_abi_sources): ...this. Also move
>>     cow-local_init.cc,
>>     > cxx11-hash_tr1.cc,
>>     >             cxx11-ios_failure.cc entries to...
>>     >             (sources): ...this.
>>     >             (extra_string_inst_sources): Move cow-fstream-inst.cc,
>>     > cow-sstream-inst.cc, cow-string-inst.cc,
>>     >             cow-string-io-inst.cc, cow-wtring-inst.cc,
>>     > cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>     >             cxx11-wlocale-inst.cc entries to...
>>     >             (inst_sources): ...this.
>>     >             * src/c++11/Makefile.in: Regenerate.
>>     >             * src/c++11/cow-fstream-inst.cc
>>     [_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++11/cow-locale_init.cc
>>     [_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++11/cow-sstream-inst.cc
>>     [_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]:
>>     > Include <bits/cow_string.h>.
>>     >             [_GLIBCXX_USE_DUAL_ABI ||
>>     > _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
>>     >             <stdexcept>. Define
>>     > _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string
>>     definition
>>     >             in <stdexcept> is skipped.
>>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS
>>     > definitions.
>>     >             * src/c++11/cow-string-inst.cc
>>     [_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++11/cow-string-io-inst.cc
>>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>     >             * src/c++11/cow-wstring-inst.cc
>>     [_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++11/cow-wstring-io-inst.cc
>>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>     >             * src/c++11/cxx11-hash_tr1.cc
>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++11/cxx11-ios_failure.cc
>>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>     >             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>     >             * src/c++11/cxx11-locale-inst.cc: Cleanup, just
>>     include
>>     > locale-inst.cc.
>>     >             * src/c++11/cxx11-stdexcept.cc
>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++11/cxx11-wlocale-inst.cc
>>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>     >             * src/c++11/locale-inst-numeric.h
>>     > [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>,
>>     > std::use_facet<num_put<>>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>,
>>     > std::has_facet<num_put<>>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C,
>>     > istreambuf_iterator<C>>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C,
>>     > ostreambuf_iterator<C>>): Instantiate.
>>     >             * src/c++11/locale-inst.cc
>>     [!_GLIBCXX_USE_DUAL_ABI]: Build
>>     > only when configured
>>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>     >             [!_GLIBCXX_USE_DUAL_ABI](time_put<C,
>>     > ostreambuf_iterator<C>>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C,
>>     > ostreambuf_iterator<C>>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char,
>>     > mbstate_t>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>>     > mbstate_t>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>>     > mbstate_t>): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char,
>>     > mbstate_t>>(const locale&)): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const
>>     locale&)):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char,
>>     > mbstate_t>>(const locale&)): Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const
>>     locale&)):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>     >             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>):
>>     > Instantiate.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long,
>>     > const C*,
>>     >             ios_base::fmtflags, bool)): Define.
>>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long
>>     > long, const C*,
>>     >             ios_base::fmtflags, bool)): Define.
>>     >             * src/c++11/string-inst.cc
>>     > (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following
>>     >             _GLIBCXX_USE_CXX11_ABI value.
>>     >             [_GLIBCXX_USE_CXX11_ABI &&
>>     > !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>     >             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS.
>>     > Include <bits/cow_string.h>.
>>     >             Define basic_string as __std_cow_string for the
>>     current
>>     > translation unit.
>>     >             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]:
>>     > Skip definitions.
>>     >             * src/c++98/Makefile.am (cxx11_abi_sources): Remove,
>>     > unique cow-istream-string.cc entry
>>     >             move to...
>>     >             (inst_sources): ...this.
>>     >             * src/c++98/Makefile.in: Regenerate.
>>     >             * src/c++98/cow-istream-string.cc: Include
>>     > <bits/c++config.h>.
>>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>     >             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip
>>     > definitions.
>>     >             * src/c++98/ios_failure.cc
>>     > [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>     >             * src/c++98/istream-string.cc
>>     [!_GLIBCXX_USE_DUAL_ABI]:
>>     > Build only when configured
>>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>     >             * src/c++98/locale_facets.cc
>>     > [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>     >             * src/c++98/stdexcept.cc
>>     > [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&):
>>     > Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&):
>>     > Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&):
>>     > Remove.
>>     > [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&):
>>     > Remove.
>>     >
>>     > Tested under linux x86_64 with following configs:
>>     >
>>     > --enable-symvers=gnu-versioned-namespace
>>     >
>>     > --disable-libstdcxx-dual-abi
>>     >
>>     > Ok to commit ?
>>     >
>>     > François
>>     >
>>     >
>>

[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 58875 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b25378eaace..322f1e42611 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     AC_MSG_NOTICE([dual ABI is disabled])
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      AC_MSG_NOTICE([dual ABI is disabled])
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c4da56c3042..fd431f28547 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,13 +70702,18 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index dd47f274d5f..b90efc81d33 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index e5f094fd13e..d5b98d30a70 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,8 +32,6 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #ifdef __cpp_lib_is_constant_evaluated
@@ -44,6 +42,10 @@
 # define __cpp_lib_constexpr_string 201611L
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -835,6 +837,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -906,6 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -933,6 +937,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -969,7 +974,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { reserve(); }
 #pragma GCC diagnostic pop
 #endif
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -978,6 +983,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1026,6 +1032,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1035,6 +1042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1345,6 +1353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1489,6 +1498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2107,6 +2117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2178,6 +2189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2192,6 +2204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2249,6 +2262,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3054,6 +3068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3257,6 +3272,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3420,6 +3436,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3481,6 +3498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3506,6 +3524,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3629,6 +3648,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3642,6 +3662,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+  #endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3682,6 +3703,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3716,7 +3738,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // 21.3.5.7 par 3: do not append null.  (good.)
       return __n;
     }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..33306508695 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,12 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
-
-  typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
+#endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
+#else
   typedef basic_string<char> __cow_string;
+#endif
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   // Emulates a new SSO string when the old std::string is in use.
   struct __sso_string
   {
@@ -94,10 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __sso_string& operator=(__sso_string&&) noexcept;
 #endif
   };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else
   typedef basic_string<char> __sso_string;
-  typedef basic_string<char> __cow_string;
 #endif
 
   /**
@@ -127,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index b4c427d487c..a43bf105308 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -963,6 +963,8 @@ class StdStringPrinter:
     def __init__(self, typename, val):
         self.val = val
         self.new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self.new_string and _versioned_namespace:
+            self.new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 5b9af41cdb9..ec0c502ecb1 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -89,6 +89,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -102,6 +105,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index f42d957af36..c9c1b65db52 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -510,14 +509,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) $(experimen
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 682be1669a4..82227338798 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -40,15 +40,11 @@ ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -59,8 +55,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -77,19 +77,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -99,6 +91,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e7a09fe3246..2d94425480b 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,25 +122,26 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = chrono.lo codecvt.lo condition_variable.lo \
-	cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
-	functional.lo futex.lo future.lo hash_c++0x.lo \
+	cow-locale_init.lo cow-stdexcept.lo ctype.lo cxx11-hash_tr1.lo \
+	cxx11-ios_failure.lo cxx11-stdexcept.lo debug.lo \
+	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
 	hashtable_c++0x.lo ios.lo ios_errcat.lo mutex.lo random.lo \
 	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
 	thread.lo $(am__objects_2) $(am__objects_3)
-@ENABLE_DUAL_ABI_TRUE@am__objects_5 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_5 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_6 = $(am__objects_5) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -461,14 +462,10 @@ host_sources = \
 	ctype_configure_char.cc \
 	ctype_members.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -478,8 +475,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -496,19 +497,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -517,6 +510,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 85277763427..6833f903f47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -165,6 +162,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -190,6 +188,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..23f853eadac 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,52 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI
+#  include <bits/cow_string.h>
+# endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+# if _GLIBCXX_USE_CXX11_ABI
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+# else
+  typedef std::string cowstr;
+# endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +155,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
-
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string() : _M_str() { }
 
+#if !_GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +190,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +497,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..25236a79950 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -70,9 +68,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
 
+#if _GLIBCXX_USE_DUAL_ABI
   // Converting constructor from ABI-tagged std::string to COW string.
   __cow_string::__cow_string(const string& s)
   : __cow_string(s.c_str(), s.length()) { }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..f29176dfc88 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,29 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#include <stdexcept>
+
+#if _GLIBCXX_USE_CXX11_ABI
+# include <bits/cow_string.h>
+typedef std::__std_cow_string<char, std::char_traits<char>,
+			      std::allocator<char>> cowstr;
+#else
+typedef std::string cowstr;
+#endif
+
+static_assert(sizeof(std::__cow_string) == sizeof(cowstr),
+	      "sizeof(std::string) has changed");
+static_assert(alignof(std::__cow_string) == alignof(cowstr),
+	      "alignof(std::string) has changed");
+#endif // _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +83,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +153,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 284ffda3443..eb24325af67 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -90,13 +90,6 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
-
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
@@ -118,6 +111,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -142,7 +136,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index a100df77a6d..d2ed2a221f2 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,31 +121,30 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_5 = parallel_settings.lo
-am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \
-	$(am__objects_5)
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \
-	localename.lo math_stubs_float.lo math_stubs_long_double.lo \
-	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
-	streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \
-	$(am__objects_6)
+am__objects_4 = parallel_settings.lo
+am__objects_5 = basic_file.lo c++locale.lo $(am__objects_3) \
+	$(am__objects_4)
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_init.lo locale_facets.lo localename.lo \
+	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
+	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
+	valarray.lo $(am__objects_2) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -471,10 +470,6 @@ host_sources_extra = \
 	basic_file.cc c++locale.cc \
 	${inst_sources} ${parallel_sources}
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -494,6 +489,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -518,7 +514,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
+
+# ifdef _GLIBCXX_USE_NLS
+#  include <libintl.h>
+#  define _(msgid)   gettext (msgid)
+# else
+#  define _(msgid)   (msgid)
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-13 19:51       ` François Dumont
@ 2023-08-17 17:17         ` François Dumont
  2023-08-24 17:33           ` François Dumont
  0 siblings, 1 reply; 20+ messages in thread
From: François Dumont @ 2023-08-17 17:17 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches


[-- Attachment #1.1: Type: text/plain, Size: 23999 bytes --]

Another fix to define __cow_string(const std::string&) in 
cxx11-stdexcept.cc even if ! _GLIBCXX_USE_DUAL_ABI.

On 13/08/2023 21:51, François Dumont wrote:
>
> Here is another version with enhanced sizeof/alignof static_assert in 
> string-inst.cc for the std::__cow_string definition from <stdexcept>. 
> The assertions in cow-stdexcept.cc are now checking the definition 
> which is in the same file.
>
> On 13/08/2023 15:27, François Dumont wrote:
>>
>> Here is the fixed patch tested in all 3 modes:
>>
>> - _GLIBCXX_USE_DUAL_ABI
>>
>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>
>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>
>> I don't know what you have in mind for the change below but I wanted 
>> to let you know that I tried to put COW std::basic_string into a 
>> nested __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more 
>> impact on string-inst.cc so I preferred the macro substitution approach.
>>
>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
>> unrelated with my changes. I'll propose fixes in coming days.
>>
>>     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>
>>     Use cxx11 abi when activating versioned namespace mode. To do support
>>     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
>> _GLIBCXX_USE_CXX11_ABI.
>>
>>     The main change is that std::__cow_string is now defined whenever 
>> _GLIBCXX_USE_DUAL_ABI
>>     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
>> available std::string in
>>     case of dual abi and a subset of it when it's not.
>>
>>     On the other side std::__sso_string is defined only when 
>> _GLIBCXX_USE_DUAL_ABI is true
>>     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
>> std::__sso_string is a typedef for the
>>     cow std::string implementation when dual abi is disabled and cow 
>> string is being used.
>>
>>     libstdcxx-v3/ChangeLog:
>>
>>             PR libstdc++/83077
>>             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
>> Default to "new" libstdcxx abi.
>>             * config/locale/dragonfly/monetary_members.cc 
>> [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>             members.
>>             * config/locale/generic/monetary_members.cc 
>> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>             * config/locale/gnu/monetary_members.cc 
>> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>             * config/locale/gnu/numeric_members.cc
>> [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>             * configure: Regenerate.
>>             * include/bits/c++config
>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
>> _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>             Define empty.
>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
>> _GLIBCXX_DEFAULT_ABI_TAG):
>>             Likewise.
>>             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
>> Define a light version of COW
>>             basic_string as __std_cow_string for use in stdexcept.
>>             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
>> __cow_string.
>>             (__cow_string(const char*)): New.
>>             (__cow_string::c_str()): New.
>>             * python/libstdcxx/v6/printers.py 
>> (StdStringPrinter::__init__): Set self.new_string to True
>>             when std::__8::basic_string type is found.
>>             * src/Makefile.am 
>> [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
>>             * src/Makefile.in: Regenerate.
>>             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>>             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
>> cxx11-hash_tr1.cc,
>>             cxx11-ios_failure.cc entries to...
>>             (sources): ...this.
>>             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
>> cow-sstream-inst.cc, cow-string-inst.cc,
>>             cow-string-io-inst.cc, cow-wtring-inst.cc, 
>> cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>             cxx11-wlocale-inst.cc entries to...
>>             (inst_sources): ...this.
>>             * src/c++11/Makefile.in: Regenerate.
>>             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Include <bits/cow_string.h>.
>>             [_GLIBCXX_USE_DUAL_ABI || 
>> _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>>             including <stdexcept>. Define 
>> _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>>             __cow_string definition in <stdexcept> is skipped.
>>             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
>> definitions.
>>             Move static_assert to check std::_cow_string abi layout to...
>>             * src/c++11/string-inst.cc: ...here.
>>             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
>> following _GLIBCXX_USE_CXX11_ABI
>>             value.
>>             [_GLIBCXX_USE_CXX11_ABI && 
>> !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
>> Include <bits/cow_string.h>.
>>             Define basic_string as __std_cow_string for the current 
>> translation unit.
>>             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-string-io-inst.cc 
>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-wstring-io-inst.cc 
>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cxx11-ios_failure.cc 
>> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
>> locale-inst.cc.
>>             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cxx11-wlocale-inst.cc 
>> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/locale-inst-numeric.h
>> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
>> std::use_facet<num_put<>>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
>> std::has_facet<num_put<>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
>> istreambuf_iterator<C>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
>> ostreambuf_iterator<C>>): Instantiate.
>>             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: 
>> Build only when configured
>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
>> ostreambuf_iterator<C>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
>> ostreambuf_iterator<C>>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
>> mbstate_t>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
>> mbstate_t>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, mbstate_t>>(const 
>> locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, mbstate_t>>(const 
>> locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
>> const C*,
>>             ios_base::fmtflags, bool)): Define.
>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
>> long, const C*,
>>             ios_base::fmtflags, bool)): Define.
>>             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, 
>> unique cow-istream-string.cc entry
>>             move to...
>>             (inst_sources): ...this.
>>             * src/c++98/Makefile.in: Regenerate.
>>             * src/c++98/cow-istream-string.cc: Include 
>> <bits/c++config.h>.
>>             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
>> definitions.
>>             * src/c++98/ios_failure.cc 
>> [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
>> Build only when configured
>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>             * src/c++98/locale_facets.cc 
>> [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>             * src/c++98/stdexcept.cc
>>             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
>> Remove.
>>
>> Ok to commit ?
>>
>> François
>>
>> On 11/08/2023 09:51, Jonathan Wakely wrote:
>>>
>>>
>>> On Fri, 11 Aug 2023, 06:44 François Dumont via Libstdc++, 
>>> <libstdc++@gcc.gnu.org <mailto:libstdc%2B%2B@gcc.gnu.org>> wrote:
>>>
>>>     I hadn't tested the most basic default configuration and it is
>>>     failing,
>>>
>>>
>>> I did wonder about that when you said which configurations you had 
>>> tested :)
>>>
>>>
>>>
>>>
>>>     I need some more time yet.
>>>
>>>
>>> OK, no problem.
>>>
>>> I actually have an idea for replacing the __cow_string hack with 
>>> something better, which I will try to work on next week. That might 
>>> make things simpler for you, as you won't need the __std_cow_string 
>>> macro.
>>>
>>>
>>>
>>>
>>>
>>>     François
>>>
>>>
>>>     On 10/08/2023 07:13, François Dumont wrote:
>>>     > Hi
>>>     >
>>>     > I've eventually completed this work.
>>>     >
>>>     > This evolution will allow to build libstdc++ without dual abi and
>>>     > using cxx11 abi. For the moment such a config is only accessible
>>>     > through the --enable-symvers=gnu-versioned-namespace
>>>     configuration.
>>>     >
>>>     >     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>>     >
>>>     >     Use cxx11 abi when activating versioned namespace mode.
>>>     >
>>>     >     libstdcxx-v3/ChangeLog:
>>>     >
>>>     >             PR libstdc++/83077
>>>     >             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]:
>>>     > Default to "new" libstdcxx abi.
>>>     >             * config/locale/dragonfly/monetary_members.cc
>>>     > [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>>     >             members.
>>>     >             * config/locale/generic/monetary_members.cc
>>>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>     >             * config/locale/gnu/monetary_members.cc
>>>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>     >             * config/locale/gnu/numeric_members.cc
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>>     >             * configure: Regenerate.
>>>     >             * include/bits/c++config
>>>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11,
>>>     > _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>>     >             Define empty.
>>>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11,
>>>     > _GLIBCXX_DEFAULT_ABI_TAG):
>>>     >             Likewise.
>>>     >             * include/bits/cow_string.h
>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>     > Define a light version of COW
>>>     >             basic_string as __std_cow_string for use in stdexcept.
>>>     >             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]:
>>>     Define
>>>     > __cow_string.
>>>     >             (__cow_string(const char*)): New.
>>>     >             (__cow_string::c_str()): New.
>>>     >             * python/libstdcxx/v6/printers.py
>>>     > (StdStringPrinter::__init__): Set self.new_string to True
>>>     >             when std::__8::basic_string type is found.
>>>     >             * src/Makefile.am
>>>     > [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources):
>>>     Define empty.
>>>     >             * src/Makefile.in: Regenerate.
>>>     >             * src/c++11/Makefile.am (cxx11_abi_sources):
>>>     Rename into...
>>>     >             (dual_abi_sources): ...this. Also move
>>>     cow-local_init.cc,
>>>     > cxx11-hash_tr1.cc,
>>>     >             cxx11-ios_failure.cc entries to...
>>>     >             (sources): ...this.
>>>     >             (extra_string_inst_sources): Move
>>>     cow-fstream-inst.cc,
>>>     > cow-sstream-inst.cc, cow-string-inst.cc,
>>>     >             cow-string-io-inst.cc, cow-wtring-inst.cc,
>>>     > cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>>     >             cxx11-wlocale-inst.cc entries to...
>>>     >             (inst_sources): ...this.
>>>     >             * src/c++11/Makefile.in: Regenerate.
>>>     >             * src/c++11/cow-fstream-inst.cc
>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++11/cow-locale_init.cc
>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++11/cow-sstream-inst.cc
>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++11/cow-stdexcept.cc
>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>     > Include <bits/cow_string.h>.
>>>     >             [_GLIBCXX_USE_DUAL_ABI ||
>>>     > _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
>>>     >             <stdexcept>. Define
>>>     > _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string
>>>     definition
>>>     >             in <stdexcept> is skipped.
>>>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS
>>>     > definitions.
>>>     >             * src/c++11/cow-string-inst.cc
>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++11/cow-string-io-inst.cc
>>>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>     >             * src/c++11/cow-wstring-inst.cc
>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++11/cow-wstring-io-inst.cc
>>>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>     >             * src/c++11/cxx11-hash_tr1.cc
>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++11/cxx11-ios_failure.cc
>>>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>     >             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>>     >             * src/c++11/cxx11-locale-inst.cc: Cleanup, just
>>>     include
>>>     > locale-inst.cc.
>>>     >             * src/c++11/cxx11-stdexcept.cc
>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++11/cxx11-wlocale-inst.cc
>>>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>     >             * src/c++11/locale-inst-numeric.h
>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>,
>>>     > std::use_facet<num_put<>>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>,
>>>     > std::has_facet<num_put<>>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C,
>>>     > istreambuf_iterator<C>>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C,
>>>     > ostreambuf_iterator<C>>): Instantiate.
>>>     >             * src/c++11/locale-inst.cc
>>>     [!_GLIBCXX_USE_DUAL_ABI]: Build
>>>     > only when configured
>>>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently built
>>>     abi.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](time_put<C,
>>>     > ostreambuf_iterator<C>>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C,
>>>     > ostreambuf_iterator<C>>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char,
>>>     > mbstate_t>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>>>     > mbstate_t>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>>>     > mbstate_t>): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char,
>>>     > mbstate_t>>(const locale&)): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const
>>>     locale&)):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char,
>>>     > mbstate_t>>(const locale&)): Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const
>>>     locale&)):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>>     >             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>):
>>>     > Instantiate.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long,
>>>     > const C*,
>>>     >             ios_base::fmtflags, bool)): Define.
>>>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long
>>>     > long, const C*,
>>>     >             ios_base::fmtflags, bool)): Define.
>>>     >             * src/c++11/string-inst.cc
>>>     > (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following
>>>     >             _GLIBCXX_USE_CXX11_ABI value.
>>>     >             [_GLIBCXX_USE_CXX11_ABI &&
>>>     > !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>>     >             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS.
>>>     > Include <bits/cow_string.h>.
>>>     >             Define basic_string as __std_cow_string for the
>>>     current
>>>     > translation unit.
>>>     >             * src/c++11/wlocale-inst.cc
>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>     > Skip definitions.
>>>     >             * src/c++98/Makefile.am (cxx11_abi_sources): Remove,
>>>     > unique cow-istream-string.cc entry
>>>     >             move to...
>>>     >             (inst_sources): ...this.
>>>     >             * src/c++98/Makefile.in: Regenerate.
>>>     >             * src/c++98/cow-istream-string.cc: Include
>>>     > <bits/c++config.h>.
>>>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>     >             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]:
>>>     Skip
>>>     > definitions.
>>>     >             * src/c++98/ios_failure.cc
>>>     > [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>>     >             * src/c++98/istream-string.cc
>>>     [!_GLIBCXX_USE_DUAL_ABI]:
>>>     > Build only when configured
>>>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently built
>>>     abi.
>>>     >             * src/c++98/locale_facets.cc
>>>     > [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>>     >             * src/c++98/stdexcept.cc
>>>     > [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&):
>>>     > Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&):
>>>     > Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&):
>>>     > Remove.
>>>     > [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&):
>>>     > Remove.
>>>     >
>>>     > Tested under linux x86_64 with following configs:
>>>     >
>>>     > --enable-symvers=gnu-versioned-namespace
>>>     >
>>>     > --disable-libstdcxx-dual-abi
>>>     >
>>>     > Ok to commit ?
>>>     >
>>>     > François
>>>     >
>>>     >
>>>

[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 58586 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b25378eaace..322f1e42611 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     AC_MSG_NOTICE([dual ABI is disabled])
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      AC_MSG_NOTICE([dual ABI is disabled])
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c4da56c3042..fd431f28547 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,13 +70702,18 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index dd47f274d5f..b90efc81d33 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index e5f094fd13e..d5b98d30a70 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,8 +32,6 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #ifdef __cpp_lib_is_constant_evaluated
@@ -44,6 +42,10 @@
 # define __cpp_lib_constexpr_string 201611L
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -835,6 +837,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -906,6 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -933,6 +937,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -969,7 +974,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { reserve(); }
 #pragma GCC diagnostic pop
 #endif
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -978,6 +983,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1026,6 +1032,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1035,6 +1042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1345,6 +1353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1489,6 +1498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2107,6 +2117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2178,6 +2189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2192,6 +2204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2249,6 +2262,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3054,6 +3068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3257,6 +3272,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3420,6 +3436,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3481,6 +3498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3506,6 +3524,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3629,6 +3648,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3642,6 +3662,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+  #endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3682,6 +3703,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3716,7 +3738,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // 21.3.5.7 par 3: do not append null.  (good.)
       return __n;
     }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..33306508695 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,12 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
-
-  typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
+#endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
+#else
   typedef basic_string<char> __cow_string;
+#endif
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   // Emulates a new SSO string when the old std::string is in use.
   struct __sso_string
   {
@@ -94,10 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __sso_string& operator=(__sso_string&&) noexcept;
 #endif
   };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else
   typedef basic_string<char> __sso_string;
-  typedef basic_string<char> __cow_string;
 #endif
 
   /**
@@ -127,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 0187c4b60e6..3475aa246ed 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -963,6 +963,8 @@ class StdStringPrinter:
     def __init__(self, typename, val):
         self.val = val
         self.new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self.new_string and _versioned_namespace:
+            self.new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 5b9af41cdb9..ec0c502ecb1 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -89,6 +89,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -102,6 +105,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index f42d957af36..c9c1b65db52 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -510,14 +509,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) $(experimen
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 682be1669a4..82227338798 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -40,15 +40,11 @@ ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -59,8 +55,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -77,19 +77,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -99,6 +91,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e7a09fe3246..2d94425480b 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,25 +122,26 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = chrono.lo codecvt.lo condition_variable.lo \
-	cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
-	functional.lo futex.lo future.lo hash_c++0x.lo \
+	cow-locale_init.lo cow-stdexcept.lo ctype.lo cxx11-hash_tr1.lo \
+	cxx11-ios_failure.lo cxx11-stdexcept.lo debug.lo \
+	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
 	hashtable_c++0x.lo ios.lo ios_errcat.lo mutex.lo random.lo \
 	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
 	thread.lo $(am__objects_2) $(am__objects_3)
-@ENABLE_DUAL_ABI_TRUE@am__objects_5 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_5 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_6 = $(am__objects_5) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -461,14 +462,10 @@ host_sources = \
 	ctype_configure_char.cc \
 	ctype_members.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -478,8 +475,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -496,19 +497,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -517,6 +510,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 85277763427..6833f903f47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -165,6 +162,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -190,6 +188,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..23f853eadac 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,52 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI
+#  include <bits/cow_string.h>
+# endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+# if _GLIBCXX_USE_CXX11_ABI
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+# else
+  typedef std::string cowstr;
+# endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +155,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
-
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string() : _M_str() { }
 
+#if !_GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +190,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +497,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..38ab35692a3 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -76,3 +74,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..f29176dfc88 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,29 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#include <stdexcept>
+
+#if _GLIBCXX_USE_CXX11_ABI
+# include <bits/cow_string.h>
+typedef std::__std_cow_string<char, std::char_traits<char>,
+			      std::allocator<char>> cowstr;
+#else
+typedef std::string cowstr;
+#endif
+
+static_assert(sizeof(std::__cow_string) == sizeof(cowstr),
+	      "sizeof(std::string) has changed");
+static_assert(alignof(std::__cow_string) == alignof(cowstr),
+	      "alignof(std::string) has changed");
+#endif // _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +83,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +153,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 284ffda3443..eb24325af67 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -90,13 +90,6 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
-
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
@@ -118,6 +111,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -142,7 +136,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index a100df77a6d..d2ed2a221f2 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,31 +121,30 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_5 = parallel_settings.lo
-am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \
-	$(am__objects_5)
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \
-	localename.lo math_stubs_float.lo math_stubs_long_double.lo \
-	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
-	streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \
-	$(am__objects_6)
+am__objects_4 = parallel_settings.lo
+am__objects_5 = basic_file.lo c++locale.lo $(am__objects_3) \
+	$(am__objects_4)
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_init.lo locale_facets.lo localename.lo \
+	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
+	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
+	valarray.lo $(am__objects_2) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -471,10 +470,6 @@ host_sources_extra = \
 	basic_file.cc c++locale.cc \
 	${inst_sources} ${parallel_sources}
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -494,6 +489,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -518,7 +514,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
+
+# ifdef _GLIBCXX_USE_NLS
+#  include <libintl.h>
+#  define _(msgid)   gettext (msgid)
+# else
+#  define _(msgid)   (msgid)
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-13 13:27     ` François Dumont
  2023-08-13 19:51       ` François Dumont
@ 2023-08-17 17:22       ` Jonathan Wakely
  2023-08-17 17:40         ` François Dumont
  2023-10-07 12:25         ` François Dumont
  1 sibling, 2 replies; 20+ messages in thread
From: Jonathan Wakely @ 2023-08-17 17:22 UTC (permalink / raw)
  To: François Dumont; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> Here is the fixed patch tested in all 3 modes:
>
> - _GLIBCXX_USE_DUAL_ABI
>
> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>
> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>
> I don't know what you have in mind for the change below but I wanted to
> let you know that I tried to put COW std::basic_string into a nested
> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
> string-inst.cc so I preferred the macro substitution approach.

I was thinking of implementing the necessary special members functions
of __cow_string directly, so they are ABI compatible with the COW
std::basic_string but don't actually reuse the code. That would mean
we don't need to compile and instantiate the whole COW string just to
use a few members from it. But that can be done later, the macro
approach seems OK for now.

>
> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
> unrelated with my changes. I'll propose fixes in coming days.

Which tests? I run the entire testsuite with
-D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
failures.

I'll review the patch ASAP, thanks for working on it.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 17:22       ` Jonathan Wakely
@ 2023-08-17 17:40         ` François Dumont
  2023-08-17 18:59           ` Jonathan Wakely
  2023-10-07 12:25         ` François Dumont
  1 sibling, 1 reply; 20+ messages in thread
From: François Dumont @ 2023-08-17 17:40 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Jonathan Wakely, libstdc++, gcc-patches


On 17/08/2023 19:22, Jonathan Wakely wrote:
> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
> <libstdc++@gcc.gnu.org> wrote:
>> Here is the fixed patch tested in all 3 modes:
>>
>> - _GLIBCXX_USE_DUAL_ABI
>>
>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>
>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>
>> I don't know what you have in mind for the change below but I wanted to
>> let you know that I tried to put COW std::basic_string into a nested
>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>> string-inst.cc so I preferred the macro substitution approach.
> I was thinking of implementing the necessary special members functions
> of __cow_string directly, so they are ABI compatible with the COW
> std::basic_string but don't actually reuse the code. That would mean
> we don't need to compile and instantiate the whole COW string just to
> use a few members from it. But that can be done later, the macro
> approach seems OK for now.

You'll see that when cow_string.h is included while 
_GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the 
basic_string definition. Initially it was to avoid to have to include 
basic_string.tcc but it is also a lot of useless code indeed.


>
>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>> unrelated with my changes. I'll propose fixes in coming days.
> Which tests? I run the entire testsuite with
> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
> failures.
>
> I'll review the patch ASAP, thanks for working on it.
>
So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI && 
!_GLIBCXX_USE_CXX11_ABI. They are:

23_containers/unordered_map/96088.cc
23_containers/unordered_multimap/96088.cc
23_containers/unordered_multiset/96088.cc
23_containers/unordered_set/96088.cc
ext/debug_allocator/check_new.cc
ext/malloc_allocator/check_new.cc
ext/malloc_allocator/deallocate_local.cc
ext/new_allocator/deallocate_local.cc
ext/pool_allocator/allocate_chunk.cc
ext/throw_allocator/deallocate_local.cc

but not sure I'll try to fix those in this context.

François


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 17:40         ` François Dumont
@ 2023-08-17 18:59           ` Jonathan Wakely
  2023-08-17 19:37             ` Jonathan Wakely
  0 siblings, 1 reply; 20+ messages in thread
From: Jonathan Wakely @ 2023-08-17 18:59 UTC (permalink / raw)
  To: François Dumont; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Thu, 17 Aug 2023 at 18:40, François Dumont <frs.dumont@gmail.com> wrote:
>
>
> On 17/08/2023 19:22, Jonathan Wakely wrote:
> > On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
> > <libstdc++@gcc.gnu.org> wrote:
> >> Here is the fixed patch tested in all 3 modes:
> >>
> >> - _GLIBCXX_USE_DUAL_ABI
> >>
> >> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
> >>
> >> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
> >>
> >> I don't know what you have in mind for the change below but I wanted to
> >> let you know that I tried to put COW std::basic_string into a nested
> >> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
> >> string-inst.cc so I preferred the macro substitution approach.
> > I was thinking of implementing the necessary special members functions
> > of __cow_string directly, so they are ABI compatible with the COW
> > std::basic_string but don't actually reuse the code. That would mean
> > we don't need to compile and instantiate the whole COW string just to
> > use a few members from it. But that can be done later, the macro
> > approach seems OK for now.
>
> You'll see that when cow_string.h is included while
> _GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the
> basic_string definition. Initially it was to avoid to have to include
> basic_string.tcc but it is also a lot of useless code indeed.
>
>
> >
> >> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
> >> unrelated with my changes. I'll propose fixes in coming days.
> > Which tests? I run the entire testsuite with
> > -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
> > failures.
> >
> > I'll review the patch ASAP, thanks for working on it.
> >
> So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI &&
> !_GLIBCXX_USE_CXX11_ABI. They are:
>
> 23_containers/unordered_map/96088.cc
> 23_containers/unordered_multimap/96088.cc
> 23_containers/unordered_multiset/96088.cc
> 23_containers/unordered_set/96088.cc
> ext/debug_allocator/check_new.cc
> ext/malloc_allocator/check_new.cc
> ext/malloc_allocator/deallocate_local.cc
> ext/new_allocator/deallocate_local.cc
> ext/pool_allocator/allocate_chunk.cc
> ext/throw_allocator/deallocate_local.cc

Ah yes, they fail for !USE_DUAL_ABI builds, I wonder why.

/home/test/src/gcc/libstdc++-v3/testsuite/23_containers/unordered_map/96088.
cc:44: void test01(): Assertion '__gnu_test::counter::count() == 3' failed.
FAIL: 23_containers/unordered_map/96088.cc execution test



> but not sure I'll try to fix those in this context.

Right, those seem like something separate.

>
> François
>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 18:59           ` Jonathan Wakely
@ 2023-08-17 19:37             ` Jonathan Wakely
  2023-08-17 19:44               ` Jonathan Wakely
  0 siblings, 1 reply; 20+ messages in thread
From: Jonathan Wakely @ 2023-08-17 19:37 UTC (permalink / raw)
  To: François Dumont; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Thu, 17 Aug 2023 at 19:59, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On Thu, 17 Aug 2023 at 18:40, François Dumont <frs.dumont@gmail.com> wrote:
> >
> >
> > On 17/08/2023 19:22, Jonathan Wakely wrote:
> > > On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
> > > <libstdc++@gcc.gnu.org> wrote:
> > >> Here is the fixed patch tested in all 3 modes:
> > >>
> > >> - _GLIBCXX_USE_DUAL_ABI
> > >>
> > >> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
> > >>
> > >> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
> > >>
> > >> I don't know what you have in mind for the change below but I wanted to
> > >> let you know that I tried to put COW std::basic_string into a nested
> > >> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
> > >> string-inst.cc so I preferred the macro substitution approach.
> > > I was thinking of implementing the necessary special members functions
> > > of __cow_string directly, so they are ABI compatible with the COW
> > > std::basic_string but don't actually reuse the code. That would mean
> > > we don't need to compile and instantiate the whole COW string just to
> > > use a few members from it. But that can be done later, the macro
> > > approach seems OK for now.
> >
> > You'll see that when cow_string.h is included while
> > _GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the
> > basic_string definition. Initially it was to avoid to have to include
> > basic_string.tcc but it is also a lot of useless code indeed.
> >
> >
> > >
> > >> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
> > >> unrelated with my changes. I'll propose fixes in coming days.
> > > Which tests? I run the entire testsuite with
> > > -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
> > > failures.
> > >
> > > I'll review the patch ASAP, thanks for working on it.
> > >
> > So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI &&
> > !_GLIBCXX_USE_CXX11_ABI. They are:
> >
> > 23_containers/unordered_map/96088.cc
> > 23_containers/unordered_multimap/96088.cc
> > 23_containers/unordered_multiset/96088.cc
> > 23_containers/unordered_set/96088.cc
> > ext/debug_allocator/check_new.cc
> > ext/malloc_allocator/check_new.cc
> > ext/malloc_allocator/deallocate_local.cc
> > ext/new_allocator/deallocate_local.cc
> > ext/pool_allocator/allocate_chunk.cc
> > ext/throw_allocator/deallocate_local.cc
>
> Ah yes, they fail for !USE_DUAL_ABI builds, I wonder why.
>
> /home/test/src/gcc/libstdc++-v3/testsuite/23_containers/unordered_map/96088.
> cc:44: void test01(): Assertion '__gnu_test::counter::count() == 3' failed.
> FAIL: 23_containers/unordered_map/96088.cc execution test

It's due to this global object in src/c++20/tzdb.cc:
1081        const string tzdata_file = "/tzdata.zi";

When the library uses COW strings that requires an allocation before
main, which uses the replacement operator new in the tests, which
fails to allocate. For example, in 22_locale/locale/cons/12352.cc we
have this function used by operator new:

int times_to_fail = 0;

void* allocate(std::size_t n)
{
  if (!times_to_fail--)
    return 0;

The counter is initially zero, so if we try to allocate before it gets
set to a non-zero value in test01() then we fail.

The test should not assume no allocations before main() begins. The
simplest way to do that is with another global that says "we have
started testing" e.g.

--- a/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
@@ -26,11 +26,12 @@
 #include <cstring>
 #include <testsuite_hooks.h>

+bool tests_started = false;
 int times_to_fail = 0;

 void* allocate(std::size_t n)
 {
-  if (!times_to_fail--)
+  if (tests_started && !times_to_fail--)
     return 0;

   void* ret = std::malloc(n ? n : 1);
@@ -106,6 +107,8 @@ void operator delete[](void* p, const
std::nothrow_t&) throw()
 // libstdc++/12352
 void test01(int iters)
 {
+  tests_started = true;
+
   for (int j = 0; j < iters; ++j)
     {
       for (int i = 0; i < 100; ++i)


This way the replacement operator new doesn't start intentionally
failing until we ask it to do so.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 19:37             ` Jonathan Wakely
@ 2023-08-17 19:44               ` Jonathan Wakely
  2023-08-17 23:31                 ` Jonathan Wakely
  2023-08-19 19:44                 ` François Dumont
  0 siblings, 2 replies; 20+ messages in thread
From: Jonathan Wakely @ 2023-08-17 19:44 UTC (permalink / raw)
  To: François Dumont; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Thu, 17 Aug 2023 at 20:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On Thu, 17 Aug 2023 at 19:59, Jonathan Wakely <jwakely@redhat.com> wrote:
> >
> > On Thu, 17 Aug 2023 at 18:40, François Dumont <frs.dumont@gmail.com> wrote:
> > >
> > >
> > > On 17/08/2023 19:22, Jonathan Wakely wrote:
> > > > On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
> > > > <libstdc++@gcc.gnu.org> wrote:
> > > >> Here is the fixed patch tested in all 3 modes:
> > > >>
> > > >> - _GLIBCXX_USE_DUAL_ABI
> > > >>
> > > >> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
> > > >>
> > > >> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
> > > >>
> > > >> I don't know what you have in mind for the change below but I wanted to
> > > >> let you know that I tried to put COW std::basic_string into a nested
> > > >> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
> > > >> string-inst.cc so I preferred the macro substitution approach.
> > > > I was thinking of implementing the necessary special members functions
> > > > of __cow_string directly, so they are ABI compatible with the COW
> > > > std::basic_string but don't actually reuse the code. That would mean
> > > > we don't need to compile and instantiate the whole COW string just to
> > > > use a few members from it. But that can be done later, the macro
> > > > approach seems OK for now.
> > >
> > > You'll see that when cow_string.h is included while
> > > _GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the
> > > basic_string definition. Initially it was to avoid to have to include
> > > basic_string.tcc but it is also a lot of useless code indeed.
> > >
> > >
> > > >
> > > >> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
> > > >> unrelated with my changes. I'll propose fixes in coming days.
> > > > Which tests? I run the entire testsuite with
> > > > -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
> > > > failures.
> > > >
> > > > I'll review the patch ASAP, thanks for working on it.
> > > >
> > > So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI &&
> > > !_GLIBCXX_USE_CXX11_ABI. They are:
> > >
> > > 23_containers/unordered_map/96088.cc
> > > 23_containers/unordered_multimap/96088.cc
> > > 23_containers/unordered_multiset/96088.cc
> > > 23_containers/unordered_set/96088.cc
> > > ext/debug_allocator/check_new.cc
> > > ext/malloc_allocator/check_new.cc
> > > ext/malloc_allocator/deallocate_local.cc
> > > ext/new_allocator/deallocate_local.cc
> > > ext/pool_allocator/allocate_chunk.cc
> > > ext/throw_allocator/deallocate_local.cc
> >
> > Ah yes, they fail for !USE_DUAL_ABI builds, I wonder why.
> >
> > /home/test/src/gcc/libstdc++-v3/testsuite/23_containers/unordered_map/96088.
> > cc:44: void test01(): Assertion '__gnu_test::counter::count() == 3' failed.
> > FAIL: 23_containers/unordered_map/96088.cc execution test
>
> It's due to this global object in src/c++20/tzdb.cc:
> 1081        const string tzdata_file = "/tzdata.zi";
>
> When the library uses COW strings that requires an allocation before
> main, which uses the replacement operator new in the tests, which
> fails to allocate. For example, in 22_locale/locale/cons/12352.cc we
> have this function used by operator new:
>
> int times_to_fail = 0;
>
> void* allocate(std::size_t n)
> {
>   if (!times_to_fail--)
>     return 0;
>
> The counter is initially zero, so if we try to allocate before it gets
> set to a non-zero value in test01() then we fail.
>
> The test should not assume no allocations before main() begins. The
> simplest way to do that is with another global that says "we have
> started testing" e.g.
>
> --- a/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
> +++ b/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
> @@ -26,11 +26,12 @@
>  #include <cstring>
>  #include <testsuite_hooks.h>
>
> +bool tests_started = false;
>  int times_to_fail = 0;
>
>  void* allocate(std::size_t n)
>  {
> -  if (!times_to_fail--)
> +  if (tests_started && !times_to_fail--)
>      return 0;
>
>    void* ret = std::malloc(n ? n : 1);
> @@ -106,6 +107,8 @@ void operator delete[](void* p, const
> std::nothrow_t&) throw()
>  // libstdc++/12352
>  void test01(int iters)
>  {
> +  tests_started = true;
> +
>    for (int j = 0; j < iters; ++j)
>      {
>        for (int i = 0; i < 100; ++i)
>
>
> This way the replacement operator new doesn't start intentionally
> failing until we ask it to do so.

I'll replace the global std::string objects with std::string_view
objects, so that they don't allocate even if the library only uses COW
strings.

We should still fix those tests though.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 19:44               ` Jonathan Wakely
@ 2023-08-17 23:31                 ` Jonathan Wakely
  2023-08-19 19:44                 ` François Dumont
  1 sibling, 0 replies; 20+ messages in thread
From: Jonathan Wakely @ 2023-08-17 23:31 UTC (permalink / raw)
  To: François Dumont; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Thu, 17 Aug 2023 at 20:44, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On Thu, 17 Aug 2023 at 20:37, Jonathan Wakely <jwakely@redhat.com> wrote:
> >
> > On Thu, 17 Aug 2023 at 19:59, Jonathan Wakely <jwakely@redhat.com> wrote:
> > >
> > > On Thu, 17 Aug 2023 at 18:40, François Dumont <frs.dumont@gmail.com> wrote:
> > > >
> > > >
> > > > On 17/08/2023 19:22, Jonathan Wakely wrote:
> > > > > On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
> > > > > <libstdc++@gcc.gnu.org> wrote:
> > > > >> Here is the fixed patch tested in all 3 modes:
> > > > >>
> > > > >> - _GLIBCXX_USE_DUAL_ABI
> > > > >>
> > > > >> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
> > > > >>
> > > > >> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
> > > > >>
> > > > >> I don't know what you have in mind for the change below but I wanted to
> > > > >> let you know that I tried to put COW std::basic_string into a nested
> > > > >> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
> > > > >> string-inst.cc so I preferred the macro substitution approach.
> > > > > I was thinking of implementing the necessary special members functions
> > > > > of __cow_string directly, so they are ABI compatible with the COW
> > > > > std::basic_string but don't actually reuse the code. That would mean
> > > > > we don't need to compile and instantiate the whole COW string just to
> > > > > use a few members from it. But that can be done later, the macro
> > > > > approach seems OK for now.
> > > >
> > > > You'll see that when cow_string.h is included while
> > > > _GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the
> > > > basic_string definition. Initially it was to avoid to have to include
> > > > basic_string.tcc but it is also a lot of useless code indeed.
> > > >
> > > >
> > > > >
> > > > >> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
> > > > >> unrelated with my changes. I'll propose fixes in coming days.
> > > > > Which tests? I run the entire testsuite with
> > > > > -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
> > > > > failures.
> > > > >
> > > > > I'll review the patch ASAP, thanks for working on it.
> > > > >
> > > > So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI &&
> > > > !_GLIBCXX_USE_CXX11_ABI. They are:
> > > >
> > > > 23_containers/unordered_map/96088.cc
> > > > 23_containers/unordered_multimap/96088.cc
> > > > 23_containers/unordered_multiset/96088.cc
> > > > 23_containers/unordered_set/96088.cc
> > > > ext/debug_allocator/check_new.cc
> > > > ext/malloc_allocator/check_new.cc
> > > > ext/malloc_allocator/deallocate_local.cc
> > > > ext/new_allocator/deallocate_local.cc
> > > > ext/pool_allocator/allocate_chunk.cc
> > > > ext/throw_allocator/deallocate_local.cc
> > >
> > > Ah yes, they fail for !USE_DUAL_ABI builds, I wonder why.
> > >
> > > /home/test/src/gcc/libstdc++-v3/testsuite/23_containers/unordered_map/96088.
> > > cc:44: void test01(): Assertion '__gnu_test::counter::count() == 3' failed.
> > > FAIL: 23_containers/unordered_map/96088.cc execution test
> >
> > It's due to this global object in src/c++20/tzdb.cc:
> > 1081        const string tzdata_file = "/tzdata.zi";
> >
> > When the library uses COW strings that requires an allocation before
> > main, which uses the replacement operator new in the tests, which
> > fails to allocate. For example, in 22_locale/locale/cons/12352.cc we
> > have this function used by operator new:
> >
> > int times_to_fail = 0;
> >
> > void* allocate(std::size_t n)
> > {
> >   if (!times_to_fail--)
> >     return 0;
> >
> > The counter is initially zero, so if we try to allocate before it gets
> > set to a non-zero value in test01() then we fail.
> >
> > The test should not assume no allocations before main() begins. The
> > simplest way to do that is with another global that says "we have
> > started testing" e.g.
> >
> > --- a/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
> > +++ b/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
> > @@ -26,11 +26,12 @@
> >  #include <cstring>
> >  #include <testsuite_hooks.h>
> >
> > +bool tests_started = false;
> >  int times_to_fail = 0;
> >
> >  void* allocate(std::size_t n)
> >  {
> > -  if (!times_to_fail--)
> > +  if (tests_started && !times_to_fail--)
> >      return 0;
> >
> >    void* ret = std::malloc(n ? n : 1);
> > @@ -106,6 +107,8 @@ void operator delete[](void* p, const
> > std::nothrow_t&) throw()
> >  // libstdc++/12352
> >  void test01(int iters)
> >  {
> > +  tests_started = true;
> > +
> >    for (int j = 0; j < iters; ++j)
> >      {
> >        for (int i = 0; i < 100; ++i)
> >
> >
> > This way the replacement operator new doesn't start intentionally
> > failing until we ask it to do so.
>
> I'll replace the global std::string objects with std::string_view
> objects, so that they don't allocate even if the library only uses COW
> strings.

Done at r14-3309-gd82a85b6161cbe

>
> We should still fix those tests though.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 19:44               ` Jonathan Wakely
  2023-08-17 23:31                 ` Jonathan Wakely
@ 2023-08-19 19:44                 ` François Dumont
  1 sibling, 0 replies; 20+ messages in thread
From: François Dumont @ 2023-08-19 19:44 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Jonathan Wakely, libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 4917 bytes --]

Here is a rebased patch following the resize_and_overwrite change.

I confirm that tests are now fixed after the change in tzdb.cc.

I'll prepare a fix for those tests still but preparing also a test to 
detect allocations in the lib.

François

On 17/08/2023 21:44, Jonathan Wakely wrote:
> On Thu, 17 Aug 2023 at 20:37, Jonathan Wakely <jwakely@redhat.com> wrote:
>> On Thu, 17 Aug 2023 at 19:59, Jonathan Wakely <jwakely@redhat.com> wrote:
>>> On Thu, 17 Aug 2023 at 18:40, François Dumont <frs.dumont@gmail.com> wrote:
>>>>
>>>> On 17/08/2023 19:22, Jonathan Wakely wrote:
>>>>> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
>>>>> <libstdc++@gcc.gnu.org> wrote:
>>>>>> Here is the fixed patch tested in all 3 modes:
>>>>>>
>>>>>> - _GLIBCXX_USE_DUAL_ABI
>>>>>>
>>>>>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>>>>>
>>>>>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>>>>>
>>>>>> I don't know what you have in mind for the change below but I wanted to
>>>>>> let you know that I tried to put COW std::basic_string into a nested
>>>>>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>>>>>> string-inst.cc so I preferred the macro substitution approach.
>>>>> I was thinking of implementing the necessary special members functions
>>>>> of __cow_string directly, so they are ABI compatible with the COW
>>>>> std::basic_string but don't actually reuse the code. That would mean
>>>>> we don't need to compile and instantiate the whole COW string just to
>>>>> use a few members from it. But that can be done later, the macro
>>>>> approach seems OK for now.
>>>> You'll see that when cow_string.h is included while
>>>> _GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the
>>>> basic_string definition. Initially it was to avoid to have to include
>>>> basic_string.tcc but it is also a lot of useless code indeed.
>>>>
>>>>
>>>>>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>>>>>> unrelated with my changes. I'll propose fixes in coming days.
>>>>> Which tests? I run the entire testsuite with
>>>>> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
>>>>> failures.
>>>>>
>>>>> I'll review the patch ASAP, thanks for working on it.
>>>>>
>>>> So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI &&
>>>> !_GLIBCXX_USE_CXX11_ABI. They are:
>>>>
>>>> 23_containers/unordered_map/96088.cc
>>>> 23_containers/unordered_multimap/96088.cc
>>>> 23_containers/unordered_multiset/96088.cc
>>>> 23_containers/unordered_set/96088.cc
>>>> ext/debug_allocator/check_new.cc
>>>> ext/malloc_allocator/check_new.cc
>>>> ext/malloc_allocator/deallocate_local.cc
>>>> ext/new_allocator/deallocate_local.cc
>>>> ext/pool_allocator/allocate_chunk.cc
>>>> ext/throw_allocator/deallocate_local.cc
>>> Ah yes, they fail for !USE_DUAL_ABI builds, I wonder why.
>>>
>>> /home/test/src/gcc/libstdc++-v3/testsuite/23_containers/unordered_map/96088.
>>> cc:44: void test01(): Assertion '__gnu_test::counter::count() == 3' failed.
>>> FAIL: 23_containers/unordered_map/96088.cc execution test
>> It's due to this global object in src/c++20/tzdb.cc:
>> 1081        const string tzdata_file = "/tzdata.zi";
>>
>> When the library uses COW strings that requires an allocation before
>> main, which uses the replacement operator new in the tests, which
>> fails to allocate. For example, in 22_locale/locale/cons/12352.cc we
>> have this function used by operator new:
>>
>> int times_to_fail = 0;
>>
>> void* allocate(std::size_t n)
>> {
>>    if (!times_to_fail--)
>>      return 0;
>>
>> The counter is initially zero, so if we try to allocate before it gets
>> set to a non-zero value in test01() then we fail.
>>
>> The test should not assume no allocations before main() begins. The
>> simplest way to do that is with another global that says "we have
>> started testing" e.g.
>>
>> --- a/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
>> +++ b/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
>> @@ -26,11 +26,12 @@
>>   #include <cstring>
>>   #include <testsuite_hooks.h>
>>
>> +bool tests_started = false;
>>   int times_to_fail = 0;
>>
>>   void* allocate(std::size_t n)
>>   {
>> -  if (!times_to_fail--)
>> +  if (tests_started && !times_to_fail--)
>>       return 0;
>>
>>     void* ret = std::malloc(n ? n : 1);
>> @@ -106,6 +107,8 @@ void operator delete[](void* p, const
>> std::nothrow_t&) throw()
>>   // libstdc++/12352
>>   void test01(int iters)
>>   {
>> +  tests_started = true;
>> +
>>     for (int j = 0; j < iters; ++j)
>>       {
>>         for (int i = 0; i < 100; ++i)
>>
>>
>> This way the replacement operator new doesn't start intentionally
>> failing until we ask it to do so.
> I'll replace the global std::string objects with std::string_view
> objects, so that they don't allocate even if the library only uses COW
> strings.
>
> We should still fix those tests though.
>

[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 58501 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b25378eaace..322f1e42611 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     AC_MSG_NOTICE([dual ABI is disabled])
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      AC_MSG_NOTICE([dual ABI is disabled])
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c4da56c3042..fd431f28547 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,13 +70702,18 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 0a41cdd29a9..ca3acfc685f 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index 5411dfe32a9..702d59faefe 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,13 +32,15 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #define __glibcxx_want_constexpr_string
 #include <bits/version.h>
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -830,6 +832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -901,6 +904,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -928,6 +932,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -1007,6 +1012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__resize_and_overwrite(size_type __n, _Operation __op);
 #endif
 
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -1015,6 +1021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1063,6 +1070,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1072,6 +1080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1382,6 +1391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1526,6 +1536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2144,6 +2155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2215,6 +2227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2229,6 +2242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2286,6 +2300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3091,6 +3106,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3294,6 +3310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3457,6 +3474,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3518,6 +3536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3543,6 +3562,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3666,6 +3686,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3679,6 +3700,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3719,6 +3741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3800,8 +3823,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 #endif // C++11
 
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..33306508695 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,12 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
-
-  typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
+#endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
+#else
   typedef basic_string<char> __cow_string;
+#endif
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   // Emulates a new SSO string when the old std::string is in use.
   struct __sso_string
   {
@@ -94,10 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __sso_string& operator=(__sso_string&&) noexcept;
 #endif
   };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else
   typedef basic_string<char> __sso_string;
-  typedef basic_string<char> __cow_string;
 #endif
 
   /**
@@ -127,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 0187c4b60e6..3475aa246ed 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -963,6 +963,8 @@ class StdStringPrinter:
     def __init__(self, typename, val):
         self.val = val
         self.new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self.new_string and _versioned_namespace:
+            self.new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 5b9af41cdb9..ec0c502ecb1 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -89,6 +89,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -102,6 +105,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index f42d957af36..c9c1b65db52 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -510,14 +509,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) $(experimen
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 682be1669a4..82227338798 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -40,15 +40,11 @@ ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -59,8 +55,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -77,19 +77,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -99,6 +91,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e7a09fe3246..2d94425480b 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,25 +122,26 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = chrono.lo codecvt.lo condition_variable.lo \
-	cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
-	functional.lo futex.lo future.lo hash_c++0x.lo \
+	cow-locale_init.lo cow-stdexcept.lo ctype.lo cxx11-hash_tr1.lo \
+	cxx11-ios_failure.lo cxx11-stdexcept.lo debug.lo \
+	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
 	hashtable_c++0x.lo ios.lo ios_errcat.lo mutex.lo random.lo \
 	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
 	thread.lo $(am__objects_2) $(am__objects_3)
-@ENABLE_DUAL_ABI_TRUE@am__objects_5 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_5 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_6 = $(am__objects_5) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -461,14 +462,10 @@ host_sources = \
 	ctype_configure_char.cc \
 	ctype_members.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -478,8 +475,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -496,19 +497,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -517,6 +510,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 85277763427..6833f903f47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -165,6 +162,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -190,6 +188,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..23f853eadac 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,52 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI
+#  include <bits/cow_string.h>
+# endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+# if _GLIBCXX_USE_CXX11_ABI
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+# else
+  typedef std::string cowstr;
+# endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +155,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
-
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string() : _M_str() { }
 
+#if !_GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +190,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +497,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..38ab35692a3 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -76,3 +74,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..f29176dfc88 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,29 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#include <stdexcept>
+
+#if _GLIBCXX_USE_CXX11_ABI
+# include <bits/cow_string.h>
+typedef std::__std_cow_string<char, std::char_traits<char>,
+			      std::allocator<char>> cowstr;
+#else
+typedef std::string cowstr;
+#endif
+
+static_assert(sizeof(std::__cow_string) == sizeof(cowstr),
+	      "sizeof(std::string) has changed");
+static_assert(alignof(std::__cow_string) == alignof(cowstr),
+	      "alignof(std::string) has changed");
+#endif // _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +83,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +153,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 284ffda3443..eb24325af67 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -90,13 +90,6 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
-
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
@@ -118,6 +111,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -142,7 +136,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index a100df77a6d..d2ed2a221f2 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,31 +121,30 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_5 = parallel_settings.lo
-am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \
-	$(am__objects_5)
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \
-	localename.lo math_stubs_float.lo math_stubs_long_double.lo \
-	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
-	streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \
-	$(am__objects_6)
+am__objects_4 = parallel_settings.lo
+am__objects_5 = basic_file.lo c++locale.lo $(am__objects_3) \
+	$(am__objects_4)
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_init.lo locale_facets.lo localename.lo \
+	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
+	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
+	valarray.lo $(am__objects_2) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -471,10 +470,6 @@ host_sources_extra = \
 	basic_file.cc c++locale.cc \
 	${inst_sources} ${parallel_sources}
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -494,6 +489,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -518,7 +514,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
+
+# ifdef _GLIBCXX_USE_NLS
+#  include <libintl.h>
+#  define _(msgid)   gettext (msgid)
+# else
+#  define _(msgid)   (msgid)
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 17:17         ` François Dumont
@ 2023-08-24 17:33           ` François Dumont
  0 siblings, 0 replies; 20+ messages in thread
From: François Dumont @ 2023-08-24 17:33 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches


[-- Attachment #1.1: Type: text/plain, Size: 24798 bytes --]

I've now prepared the patch to support following config:

--disable-libstdcxx-dual-abi --with-default-libstdcxx-abi=new

and so detected yet another problem with src/c++98/compatibility.cc. We 
need basic_istream<>::ignore(streamsize) definitions that rely here but 
not the rest of it.

François

On 17/08/2023 19:17, François Dumont wrote:
>
> Another fix to define __cow_string(const std::string&) in 
> cxx11-stdexcept.cc even if ! _GLIBCXX_USE_DUAL_ABI.
>
> On 13/08/2023 21:51, François Dumont wrote:
>>
>> Here is another version with enhanced sizeof/alignof static_assert in 
>> string-inst.cc for the std::__cow_string definition from <stdexcept>. 
>> The assertions in cow-stdexcept.cc are now checking the definition 
>> which is in the same file.
>>
>> On 13/08/2023 15:27, François Dumont wrote:
>>>
>>> Here is the fixed patch tested in all 3 modes:
>>>
>>> - _GLIBCXX_USE_DUAL_ABI
>>>
>>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>>
>>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>>
>>> I don't know what you have in mind for the change below but I wanted 
>>> to let you know that I tried to put COW std::basic_string into a 
>>> nested __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more 
>>> impact on string-inst.cc so I preferred the macro substitution approach.
>>>
>>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
>>> unrelated with my changes. I'll propose fixes in coming days.
>>>
>>>     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>>
>>>     Use cxx11 abi when activating versioned namespace mode. To do 
>>> support
>>>     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
>>> _GLIBCXX_USE_CXX11_ABI.
>>>
>>>     The main change is that std::__cow_string is now defined 
>>> whenever _GLIBCXX_USE_DUAL_ABI
>>>     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
>>> available std::string in
>>>     case of dual abi and a subset of it when it's not.
>>>
>>>     On the other side std::__sso_string is defined only when 
>>> _GLIBCXX_USE_DUAL_ABI is true
>>>     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
>>> std::__sso_string is a typedef for the
>>>     cow std::string implementation when dual abi is disabled and cow 
>>> string is being used.
>>>
>>>     libstdcxx-v3/ChangeLog:
>>>
>>>             PR libstdc++/83077
>>>             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
>>> Default to "new" libstdcxx abi.
>>>             * config/locale/dragonfly/monetary_members.cc 
>>> [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>>             members.
>>>             * config/locale/generic/monetary_members.cc 
>>> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>             * config/locale/gnu/monetary_members.cc 
>>> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>             * config/locale/gnu/numeric_members.cc
>>> [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>>             * configure: Regenerate.
>>>             * include/bits/c++config
>>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
>>> _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>>             Define empty.
>>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
>>> _GLIBCXX_DEFAULT_ABI_TAG):
>>>             Likewise.
>>>             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
>>> Define a light version of COW
>>>             basic_string as __std_cow_string for use in stdexcept.
>>>             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
>>> __cow_string.
>>>             (__cow_string(const char*)): New.
>>>             (__cow_string::c_str()): New.
>>>             * python/libstdcxx/v6/printers.py 
>>> (StdStringPrinter::__init__): Set self.new_string to True
>>>             when std::__8::basic_string type is found.
>>>             * src/Makefile.am 
>>> [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define 
>>> empty.
>>>             * src/Makefile.in: Regenerate.
>>>             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>>>             (dual_abi_sources): ...this. Also move 
>>> cow-local_init.cc, cxx11-hash_tr1.cc,
>>>             cxx11-ios_failure.cc entries to...
>>>             (sources): ...this.
>>>             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
>>> cow-sstream-inst.cc, cow-string-inst.cc,
>>>             cow-string-io-inst.cc, cow-wtring-inst.cc, 
>>> cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>>             cxx11-wlocale-inst.cc entries to...
>>>             (inst_sources): ...this.
>>>             * src/c++11/Makefile.in: Regenerate.
>>>             * src/c++11/cow-fstream-inst.cc 
>>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
>>> Skip definitions.
>>>             * src/c++11/cow-sstream-inst.cc 
>>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
>>> Include <bits/cow_string.h>.
>>>             [_GLIBCXX_USE_DUAL_ABI || 
>>> _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>>>             including <stdexcept>. Define 
>>> _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>>>             __cow_string definition in <stdexcept> is skipped.
>>>             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
>>> definitions.
>>>             Move static_assert to check std::_cow_string abi layout 
>>> to...
>>>             * src/c++11/string-inst.cc: ...here.
>>>             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
>>> following _GLIBCXX_USE_CXX11_ABI
>>>             value.
>>>             [_GLIBCXX_USE_CXX11_ABI && 
>>> !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>>             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
>>> Include <bits/cow_string.h>.
>>>             Define basic_string as __std_cow_string for the current 
>>> translation unit.
>>>             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>>> Skip definitions.
>>>             * src/c++11/cow-string-io-inst.cc 
>>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++11/cow-wstring-inst.cc 
>>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++11/cow-wstring-io-inst.cc 
>>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>>> Skip definitions.
>>>             * src/c++11/cxx11-ios_failure.cc 
>>> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>>             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
>>> locale-inst.cc.
>>>             * src/c++11/cxx11-stdexcept.cc 
>>> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++11/cxx11-wlocale-inst.cc 
>>> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++11/locale-inst-numeric.h
>>> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
>>> std::use_facet<num_put<>>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
>>> std::has_facet<num_put<>>): Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
>>> istreambuf_iterator<C>>): Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
>>> ostreambuf_iterator<C>>): Instantiate.
>>>             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: 
>>> Build only when configured
>>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>> [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
>>> ostreambuf_iterator<C>>): Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
>>> ostreambuf_iterator<C>>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
>>> mbstate_t>): Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
>>> mbstate_t>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): 
>>> Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
>>> mbstate_t>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
>>> Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
>>> Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): 
>>> Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
>>> mbstate_t>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
>>> Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
>>> Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>>             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
>>> Instantiate.
>>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned 
>>> long, const C*,
>>>             ios_base::fmtflags, bool)): Define.
>>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
>>> long, const C*,
>>>             ios_base::fmtflags, bool)): Define.
>>>             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>>> Skip definitions.
>>>             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, 
>>> unique cow-istream-string.cc entry
>>>             move to...
>>>             (inst_sources): ...this.
>>>             * src/c++98/Makefile.in: Regenerate.
>>>             * src/c++98/cow-istream-string.cc: Include 
>>> <bits/c++config.h>.
>>>             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
>>> definitions.
>>>             * src/c++98/ios_failure.cc 
>>> [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>>             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
>>> Build only when configured
>>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>>             * src/c++98/locale_facets.cc 
>>> [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>>             * src/c++98/stdexcept.cc
>>>             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): 
>>> Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const 
>>> string&): Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): 
>>> Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): 
>>> Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): 
>>> Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): 
>>> Remove.
>>>             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
>>> Remove.
>>>
>>> Ok to commit ?
>>>
>>> François
>>>
>>> On 11/08/2023 09:51, Jonathan Wakely wrote:
>>>>
>>>>
>>>> On Fri, 11 Aug 2023, 06:44 François Dumont via Libstdc++, 
>>>> <libstdc++@gcc.gnu.org <mailto:libstdc%2B%2B@gcc.gnu.org>> wrote:
>>>>
>>>>     I hadn't tested the most basic default configuration and it is
>>>>     failing,
>>>>
>>>>
>>>> I did wonder about that when you said which configurations you had 
>>>> tested :)
>>>>
>>>>
>>>>
>>>>
>>>>     I need some more time yet.
>>>>
>>>>
>>>> OK, no problem.
>>>>
>>>> I actually have an idea for replacing the __cow_string hack with 
>>>> something better, which I will try to work on next week. That might 
>>>> make things simpler for you, as you won't need the __std_cow_string 
>>>> macro.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>     François
>>>>
>>>>
>>>>     On 10/08/2023 07:13, François Dumont wrote:
>>>>     > Hi
>>>>     >
>>>>     > I've eventually completed this work.
>>>>     >
>>>>     > This evolution will allow to build libstdc++ without dual abi
>>>>     and
>>>>     > using cxx11 abi. For the moment such a config is only accessible
>>>>     > through the --enable-symvers=gnu-versioned-namespace
>>>>     configuration.
>>>>     >
>>>>     >     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>>>     >
>>>>     >     Use cxx11 abi when activating versioned namespace mode.
>>>>     >
>>>>     >     libstdcxx-v3/ChangeLog:
>>>>     >
>>>>     >             PR libstdc++/83077
>>>>     >             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]:
>>>>     > Default to "new" libstdcxx abi.
>>>>     >             * config/locale/dragonfly/monetary_members.cc
>>>>     > [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>>>     >             members.
>>>>     >             * config/locale/generic/monetary_members.cc
>>>>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>>     >             * config/locale/gnu/monetary_members.cc
>>>>     > [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>>     >             * config/locale/gnu/numeric_members.cc
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>>>     >             * configure: Regenerate.
>>>>     >             * include/bits/c++config
>>>>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11,
>>>>     > _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>>>     >             Define empty.
>>>>     > [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11,
>>>>     > _GLIBCXX_DEFAULT_ABI_TAG):
>>>>     >             Likewise.
>>>>     >             * include/bits/cow_string.h
>>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Define a light version of COW
>>>>     >             basic_string as __std_cow_string for use in
>>>>     stdexcept.
>>>>     >             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]:
>>>>     Define
>>>>     > __cow_string.
>>>>     >             (__cow_string(const char*)): New.
>>>>     >             (__cow_string::c_str()): New.
>>>>     >             * python/libstdcxx/v6/printers.py
>>>>     > (StdStringPrinter::__init__): Set self.new_string to True
>>>>     >             when std::__8::basic_string type is found.
>>>>     >             * src/Makefile.am
>>>>     > [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources):
>>>>     Define empty.
>>>>     >             * src/Makefile.in: Regenerate.
>>>>     >             * src/c++11/Makefile.am (cxx11_abi_sources):
>>>>     Rename into...
>>>>     >             (dual_abi_sources): ...this. Also move
>>>>     cow-local_init.cc,
>>>>     > cxx11-hash_tr1.cc,
>>>>     >             cxx11-ios_failure.cc entries to...
>>>>     >             (sources): ...this.
>>>>     >             (extra_string_inst_sources): Move
>>>>     cow-fstream-inst.cc,
>>>>     > cow-sstream-inst.cc, cow-string-inst.cc,
>>>>     >             cow-string-io-inst.cc, cow-wtring-inst.cc,
>>>>     > cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>>>     >             cxx11-wlocale-inst.cc entries to...
>>>>     >             (inst_sources): ...this.
>>>>     >             * src/c++11/Makefile.in: Regenerate.
>>>>     >             * src/c++11/cow-fstream-inst.cc
>>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++11/cow-locale_init.cc
>>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++11/cow-sstream-inst.cc
>>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++11/cow-stdexcept.cc
>>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Include <bits/cow_string.h>.
>>>>     >             [_GLIBCXX_USE_DUAL_ABI ||
>>>>     > _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
>>>>     >             <stdexcept>. Define
>>>>     > _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string
>>>>     definition
>>>>     >             in <stdexcept> is skipped.
>>>>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS
>>>>     > definitions.
>>>>     >             * src/c++11/cow-string-inst.cc
>>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++11/cow-string-io-inst.cc
>>>>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>>     >             * src/c++11/cow-wstring-inst.cc
>>>>     [_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++11/cow-wstring-io-inst.cc
>>>>     > [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>>     >             * src/c++11/cxx11-hash_tr1.cc
>>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++11/cxx11-ios_failure.cc
>>>>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>>     >             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>>>     >             * src/c++11/cxx11-locale-inst.cc: Cleanup, just
>>>>     include
>>>>     > locale-inst.cc.
>>>>     >             * src/c++11/cxx11-stdexcept.cc
>>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++11/cxx11-wlocale-inst.cc
>>>>     > [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>>     >             * src/c++11/locale-inst-numeric.h
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>,
>>>>     > std::use_facet<num_put<>>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>,
>>>>     > std::has_facet<num_put<>>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C,
>>>>     > istreambuf_iterator<C>>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C,
>>>>     > ostreambuf_iterator<C>>): Instantiate.
>>>>     >             * src/c++11/locale-inst.cc
>>>>     [!_GLIBCXX_USE_DUAL_ABI]: Build
>>>>     > only when configured
>>>>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently
>>>>     built abi.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](time_put<C,
>>>>     > ostreambuf_iterator<C>>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C,
>>>>     > ostreambuf_iterator<C>>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char,
>>>>     > mbstate_t>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>>>>     > mbstate_t>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char,
>>>>     > mbstate_t>): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char,
>>>>     > mbstate_t>>(const locale&)): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const
>>>>     locale&)):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char,
>>>>     > mbstate_t>>(const locale&)): Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const
>>>>     locale&)):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>):
>>>>     > Instantiate.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long,
>>>>     > const C*,
>>>>     >             ios_base::fmtflags, bool)): Define.
>>>>     > [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long
>>>>     > long, const C*,
>>>>     >             ios_base::fmtflags, bool)): Define.
>>>>     >             * src/c++11/string-inst.cc
>>>>     > (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following
>>>>     >             _GLIBCXX_USE_CXX11_ABI value.
>>>>     >             [_GLIBCXX_USE_CXX11_ABI &&
>>>>     > !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>>>     >             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS.
>>>>     > Include <bits/cow_string.h>.
>>>>     >             Define basic_string as __std_cow_string for the
>>>>     current
>>>>     > translation unit.
>>>>     >             * src/c++11/wlocale-inst.cc
>>>>     [!_GLIBCXX_USE_CXX11_ABI]:
>>>>     > Skip definitions.
>>>>     >             * src/c++98/Makefile.am (cxx11_abi_sources): Remove,
>>>>     > unique cow-istream-string.cc entry
>>>>     >             move to...
>>>>     >             (inst_sources): ...this.
>>>>     >             * src/c++98/Makefile.in: Regenerate.
>>>>     >             * src/c++98/cow-istream-string.cc: Include
>>>>     > <bits/c++config.h>.
>>>>     >             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>>     >             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]:
>>>>     Skip
>>>>     > definitions.
>>>>     >             * src/c++98/ios_failure.cc
>>>>     > [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip
>>>>     definitions.
>>>>     >             * src/c++98/istream-string.cc
>>>>     [!_GLIBCXX_USE_DUAL_ABI]:
>>>>     > Build only when configured
>>>>     >             _GLIBCXX_USE_CXX11_ABI is equal to currently
>>>>     built abi.
>>>>     >             * src/c++98/locale_facets.cc
>>>>     > [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>>>     >             * src/c++98/stdexcept.cc
>>>>     > [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&):
>>>>     > Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&):
>>>>     > Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&):
>>>>     > Remove.
>>>>     > [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&):
>>>>     > Remove.
>>>>     >
>>>>     > Tested under linux x86_64 with following configs:
>>>>     >
>>>>     > --enable-symvers=gnu-versioned-namespace
>>>>     >
>>>>     > --disable-libstdcxx-dual-abi
>>>>     >
>>>>     > Ok to commit ?
>>>>     >
>>>>     > François
>>>>     >
>>>>     >
>>>>

[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 59873 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b25378eaace..322f1e42611 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     AC_MSG_NOTICE([dual ABI is disabled])
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      AC_MSG_NOTICE([dual ABI is disabled])
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c4da56c3042..fd431f28547 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,13 +70702,18 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index a917fb58225..f43fd9b2276 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index 5411dfe32a9..702d59faefe 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,13 +32,15 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #define __glibcxx_want_constexpr_string
 #include <bits/version.h>
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -830,6 +832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -901,6 +904,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -928,6 +932,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -1007,6 +1012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__resize_and_overwrite(size_type __n, _Operation __op);
 #endif
 
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -1015,6 +1021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1063,6 +1070,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1072,6 +1080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1382,6 +1391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1526,6 +1536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2144,6 +2155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2215,6 +2227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2229,6 +2242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2286,6 +2300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3091,6 +3106,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3294,6 +3310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3457,6 +3474,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3518,6 +3536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3543,6 +3562,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3666,6 +3686,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3679,6 +3700,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3719,6 +3741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3800,8 +3823,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 #endif // C++11
 
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..33306508695 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,12 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
-
-  typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
+#endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
+#else
   typedef basic_string<char> __cow_string;
+#endif
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   // Emulates a new SSO string when the old std::string is in use.
   struct __sso_string
   {
@@ -94,10 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __sso_string& operator=(__sso_string&&) noexcept;
 #endif
   };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else
   typedef basic_string<char> __sso_string;
-  typedef basic_string<char> __cow_string;
 #endif
 
   /**
@@ -127,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 0187c4b60e6..3475aa246ed 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -963,6 +963,8 @@ class StdStringPrinter:
     def __init__(self, typename, val):
         self.val = val
         self.new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self.new_string and _versioned_namespace:
+            self.new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 5b9af41cdb9..ec0c502ecb1 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -89,6 +89,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -102,6 +105,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index f42d957af36..c9c1b65db52 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -510,14 +509,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) $(experimen
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 682be1669a4..82227338798 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -40,15 +40,11 @@ ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -59,8 +55,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -77,19 +77,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -99,6 +91,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e7a09fe3246..2d94425480b 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,25 +122,26 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = chrono.lo codecvt.lo condition_variable.lo \
-	cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
-	functional.lo futex.lo future.lo hash_c++0x.lo \
+	cow-locale_init.lo cow-stdexcept.lo ctype.lo cxx11-hash_tr1.lo \
+	cxx11-ios_failure.lo cxx11-stdexcept.lo debug.lo \
+	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
 	hashtable_c++0x.lo ios.lo ios_errcat.lo mutex.lo random.lo \
 	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
 	thread.lo $(am__objects_2) $(am__objects_3)
-@ENABLE_DUAL_ABI_TRUE@am__objects_5 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_5 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_6 = $(am__objects_5) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -461,14 +462,10 @@ host_sources = \
 	ctype_configure_char.cc \
 	ctype_members.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -478,8 +475,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -496,19 +497,11 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -517,6 +510,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index 85277763427..6833f903f47 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -165,6 +162,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -190,6 +188,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..23f853eadac 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,52 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI
+#  include <bits/cow_string.h>
+# endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+# if _GLIBCXX_USE_CXX11_ABI
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+# else
+  typedef std::string cowstr;
+# endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +155,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
-
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string() : _M_str() { }
 
+#if !_GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +190,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +497,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..38ab35692a3 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -76,3 +74,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..f29176dfc88 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,29 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#include <stdexcept>
+
+#if _GLIBCXX_USE_CXX11_ABI
+# include <bits/cow_string.h>
+typedef std::__std_cow_string<char, std::char_traits<char>,
+			      std::allocator<char>> cowstr;
+#else
+typedef std::string cowstr;
+#endif
+
+static_assert(sizeof(std::__cow_string) == sizeof(cowstr),
+	      "sizeof(std::string) has changed");
+static_assert(alignof(std::__cow_string) == alignof(cowstr),
+	      "alignof(std::string) has changed");
+#endif // _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +83,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +153,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 284ffda3443..eb24325af67 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -90,13 +90,6 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
-
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
@@ -118,6 +111,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -142,7 +136,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index a100df77a6d..d2ed2a221f2 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,31 +121,30 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_5 = parallel_settings.lo
-am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \
-	$(am__objects_5)
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \
-	localename.lo math_stubs_float.lo math_stubs_long_double.lo \
-	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
-	streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \
-	$(am__objects_6)
+am__objects_4 = parallel_settings.lo
+am__objects_5 = basic_file.lo c++locale.lo $(am__objects_3) \
+	$(am__objects_4)
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_init.lo locale_facets.lo localename.lo \
+	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
+	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
+	valarray.lo $(am__objects_2) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -471,10 +470,6 @@ host_sources_extra = \
 	basic_file.cc c++locale.cc \
 	${inst_sources} ${parallel_sources}
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -494,6 +489,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -518,7 +514,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc
index 5ff21f09c43..b7feae2649d 100644
--- a/libstdc++-v3/src/c++98/compatibility.cc
+++ b/libstdc++-v3/src/c++98/compatibility.cc
@@ -25,7 +25,8 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \
+#if ! _GLIBCXX_USE_CXX11_ABI \
+    && defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED)	\
     && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE)\
     && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
 #define istreambuf_iterator istreambuf_iteratorXX
@@ -220,7 +221,8 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 // NB: These symbols renames should go into the shared library only,
 // and only those shared libraries that support versioning.
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \
+#if ! _GLIBCXX_USE_CXX11_ABI \
+    && defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED)	\
     && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \
     && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
 
@@ -525,7 +527,7 @@ _GLIBCXX_MATHL_WRAPPER1 (tan, GLIBCXX_3.4);
 #endif
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
 
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
 extern void *_ZTVN10__cxxabiv123__fundamental_type_infoE[];
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
+
+# ifdef _GLIBCXX_USE_NLS
+#  include <libintl.h>
+#  define _(msgid)   gettext (msgid)
+# else
+#  define _(msgid)   (msgid)
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-08-17 17:22       ` Jonathan Wakely
  2023-08-17 17:40         ` François Dumont
@ 2023-10-07 12:25         ` François Dumont
  2023-10-07 19:32           ` François Dumont
  1 sibling, 1 reply; 20+ messages in thread
From: François Dumont @ 2023-10-07 12:25 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Jonathan Wakely, libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 12227 bytes --]

Hi

Here is a rebased version of this patch.

There are few test failures when running 'make check-c++' but nothing new.

Still, there are 2 patches awaiting validation to fix some of them, PR 
c++/111524 to fix another bunch and I fear that we will have to live 
with the others.

     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

     Use cxx11 abi when activating versioned namespace mode. To do support
     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
_GLIBCXX_USE_CXX11_ABI.

     The main change is that std::__cow_string is now defined whenever 
_GLIBCXX_USE_DUAL_ABI
     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
available std::string in
     case of dual abi and a subset of it when it's not.

     On the other side std::__sso_string is defined only when 
_GLIBCXX_USE_DUAL_ABI is true
     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that std::__sso_string 
is a typedef for the
     cow std::string implementation when dual abi is disabled and cow 
string is being used.

     libstdcxx-v3/ChangeLog:

             PR libstdc++/83077
             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default 
to "new" libstdcxx abi
             when enable_symvers is gnu-versioned-namespace.
             * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base
             members.
             * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
             * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
             * config/locale/gnu/numeric_members.cc
             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
             * configure: Regenerate.
             * include/bits/c++config
             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):
             Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):
             Likewise.
             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW
             basic_string as __std_cow_string for use in stdexcept.
             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.
             (__cow_string(const char*)): New.
             (__cow_string::c_str()): New.
             * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True
             when std::__8::basic_string type is found.
             * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
             * src/Makefile.in: Regenerate.
             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,
             cxx11-ios_failure.cc entries to...
             (sources): ...this.
             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
             cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
             cxx11-wlocale-inst.cc entries to...
             (inst_sources): ...this.
             * src/c++11/Makefile.in: Regenerate.
             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include <bits/cow_string.h>.
             [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
             including <stdexcept>. Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
             __cow_string definition in <stdexcept> is skipped.
             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
             * src/c++11/string-inst.cc: Add sizeof/alignof 
static_assert on stdexcept
             __cow_string definition.
             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
following _GLIBCXX_USE_CXX11_ABI
             value.
             [_GLIBCXX_USE_CXX11_ABI && 
!_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. Include 
<bits/cow_string.h>.
             Define basic_string as __std_cow_string for the current 
translation unit.
             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
locale-inst.cc.
             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
             * src/c++11/cxx11-wlocale-inst.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
std::use_facet<num_put<>>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
std::has_facet<num_put<>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
istreambuf_iterator<C>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
ostreambuf_iterator<C>>): Instantiate.
             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
only when configured
             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
ostreambuf_iterator<C>>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
ostreambuf_iterator<C>>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
mbstate_t>): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
mbstate_t>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
mbstate_t>>(const locale&)): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
mbstate_t>>(const locale&)): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
Instantiate.
             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
const C*,
             ios_base::fmtflags, bool)): Define.
             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
long, const C*,
             ios_base::fmtflags, bool)): Define.
             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip 
definitions.
             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, unique 
cow-istream-string.cc entry
             move to...
             (inst_sources): ...this.
             * src/c++98/Makefile.in: Regenerate.
             * src/c++98/cow-istream-string.cc: Include <bits/c++config.h>.
             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
definitions.
             * src/c++98/ios_failure.cc 
[_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
Build only when configured
             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
             * src/c++98/locale_facets.cc 
[_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
             * src/c++98/stdexcept.cc
             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
Remove.
             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): Remove.
             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
Remove.
             * src/c++98/compatibility.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
all definitions appart from
             istream::ignore(streamsize).

Tested under Linux x64_86, ok to commit ?

François


On 17/08/2023 19:22, Jonathan Wakely wrote:
> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
> <libstdc++@gcc.gnu.org> wrote:
>> Here is the fixed patch tested in all 3 modes:
>>
>> - _GLIBCXX_USE_DUAL_ABI
>>
>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>
>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>
>> I don't know what you have in mind for the change below but I wanted to
>> let you know that I tried to put COW std::basic_string into a nested
>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>> string-inst.cc so I preferred the macro substitution approach.
> I was thinking of implementing the necessary special members functions
> of __cow_string directly, so they are ABI compatible with the COW
> std::basic_string but don't actually reuse the code. That would mean
> we don't need to compile and instantiate the whole COW string just to
> use a few members from it. But that can be done later, the macro
> approach seems OK for now.
>
>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>> unrelated with my changes. I'll propose fixes in coming days.
> Which tests? I run the entire testsuite with
> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
> failures.
>
> I'll review the patch ASAP, thanks for working on it.
>

[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 60209 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index d8f0ba1c3e2..793471216e6 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,13 +4875,17 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
+    # gnu-versioned-namespace is incompatible with the dual ABI...
+    AC_MSG_NOTICE([dual ABI is disabled])
     enable_libstdcxx_dual_abi="no"
-  fi
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
     if test x"$enable_libstdcxx_dual_abi" != xyes; then
       AC_MSG_NOTICE([dual ABI is disabled])
       default_libstdcxx_abi="gcc4-compatible"
     fi
+  fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
 
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 13fc03b2a3f..58e01f7d16f 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,14 +70702,19 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
+    # gnu-versioned-namespace is incompatible with the dual ABI...
+    { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
     enable_libstdcxx_dual_abi="no"
-  fi
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
     if test x"$enable_libstdcxx_dual_abi" != xyes; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
       default_libstdcxx_abi="gcc4-compatible"
     fi
+  fi
 
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 410c136e1b1..3367179c1c3 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index 5411dfe32a9..702d59faefe 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,13 +32,15 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #define __glibcxx_want_constexpr_string
 #include <bits/version.h>
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -830,6 +832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -901,6 +904,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -928,6 +932,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -1007,6 +1012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__resize_and_overwrite(size_type __n, _Operation __op);
 #endif
 
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -1015,6 +1021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1063,6 +1070,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1072,6 +1080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1382,6 +1391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1526,6 +1536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2144,6 +2155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2215,6 +2227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2229,6 +2242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2286,6 +2300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3091,6 +3106,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3294,6 +3310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3457,6 +3474,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3518,6 +3536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3543,6 +3562,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3666,6 +3686,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3679,6 +3700,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3719,6 +3741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3800,8 +3823,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 #endif // C++11
 
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..33306508695 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,12 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
-
-  typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
+#endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
+#else
   typedef basic_string<char> __cow_string;
+#endif
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   // Emulates a new SSO string when the old std::string is in use.
   struct __sso_string
   {
@@ -94,10 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __sso_string& operator=(__sso_string&&) noexcept;
 #endif
   };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else
   typedef basic_string<char> __sso_string;
-  typedef basic_string<char> __cow_string;
 #endif
 
   /**
@@ -127,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 7e16a49aeb0..81785a6e66b 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1029,6 +1029,8 @@ class StdStringPrinter(printer_base):
     def __init__(self, typename, val):
         self._val = val
         self._new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self._new_string:
+            self._new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 32de5304122..16f46faf91a 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -91,6 +91,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -104,6 +107,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index c5d01e7beba..17618c278bc 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -512,14 +511,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 c++23 \
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 9cddb978928..be8e35754b8 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -48,15 +48,11 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -68,8 +64,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -88,20 +88,12 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -111,6 +103,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e6d37c5464c..171ff1adf16 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,27 +122,28 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = basic_file.lo
 am__objects_5 = assert_fail.lo chrono.lo codecvt.lo \
-	condition_variable.lo cow-stdexcept.lo ctype.lo debug.lo \
-	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
-	hashtable_c++0x.lo ios.lo ios_errcat.lo locale_init.lo \
-	localename.lo mutex.lo random.lo regex.lo shared_ptr.lo \
-	snprintf_lite.lo system_error.lo thread.lo $(am__objects_2) \
-	$(am__objects_3) $(am__objects_4)
-@ENABLE_DUAL_ABI_TRUE@am__objects_6 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+	condition_variable.lo cow-locale_init.lo cow-stdexcept.lo \
+	ctype.lo cxx11-hash_tr1.lo cxx11-ios_failure.lo \
+	cxx11-stdexcept.lo debug.lo functexcept.lo functional.lo \
+	futex.lo future.lo hash_c++0x.lo hashtable_c++0x.lo ios.lo \
+	ios_errcat.lo locale_init.lo localename.lo mutex.lo random.lo \
+	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
+	thread.lo $(am__objects_2) $(am__objects_3) $(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@am__objects_6 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_7 = $(am__objects_6) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -469,14 +470,10 @@ host_sources = \
 host_sources_extra = \
 	basic_file.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -487,8 +484,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -507,20 +508,12 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -529,6 +522,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index f48561f5b12..bfe1d19db04 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -166,6 +163,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -191,6 +189,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..23f853eadac 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,52 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI
+#  include <bits/cow_string.h>
+# endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+# if _GLIBCXX_USE_CXX11_ABI
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+# else
+  typedef std::string cowstr;
+# endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +155,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
-
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string() : _M_str() { }
 
+#if !_GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +190,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +497,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..38ab35692a3 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -76,3 +74,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..f29176dfc88 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,29 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#include <stdexcept>
+
+#if _GLIBCXX_USE_CXX11_ABI
+# include <bits/cow_string.h>
+typedef std::__std_cow_string<char, std::char_traits<char>,
+			      std::allocator<char>> cowstr;
+#else
+typedef std::string cowstr;
+#endif
+
+static_assert(sizeof(std::__cow_string) == sizeof(cowstr),
+	      "sizeof(std::string) has changed");
+static_assert(alignof(std::__cow_string) == alignof(cowstr),
+	      "alignof(std::string) has changed");
+#endif // _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +83,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +153,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 72be2d2d2ea..86242397d33 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -86,12 +86,8 @@ host_sources_extra = \
 c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CLOCALE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
+basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
+	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
@@ -114,6 +110,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -136,7 +133,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra} \
 	${inst_sources} \
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 95e909b1049..761fbcf6135 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,30 +121,29 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-am__objects_4 = c++locale.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_5 = allocator-inst.lo \
+am__objects_3 = c++locale.lo
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_6 = parallel_settings.lo
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_facets.lo \
-	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
-	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
-	valarray.lo $(am__objects_1) $(am__objects_3) $(am__objects_4) \
-	$(am__objects_5) $(am__objects_6)
+am__objects_5 = parallel_settings.lo
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_facets.lo math_stubs_float.lo math_stubs_long_double.lo \
+	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
+	streambuf.lo valarray.lo $(am__objects_2) $(am__objects_3) \
+	$(am__objects_4) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -469,10 +468,6 @@ host_sources = \
 host_sources_extra = \
 	c++locale.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -492,6 +487,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -514,7 +510,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra} \
 	${inst_sources} \
@@ -869,6 +864,9 @@ time_members.cc: ${glibcxx_srcdir}/$(CTIME_CC)
 c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CLOCALE_CC) ./$@ || true
 
+basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
+	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
+
 vpath % $(top_srcdir)/src/c++98
 
 # Use special rules to compile with -fimplicit-templates.
diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc
index 5ff21f09c43..b7feae2649d 100644
--- a/libstdc++-v3/src/c++98/compatibility.cc
+++ b/libstdc++-v3/src/c++98/compatibility.cc
@@ -25,7 +25,8 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \
+#if ! _GLIBCXX_USE_CXX11_ABI \
+    && defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED)	\
     && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE)\
     && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
 #define istreambuf_iterator istreambuf_iteratorXX
@@ -220,7 +221,8 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 // NB: These symbols renames should go into the shared library only,
 // and only those shared libraries that support versioning.
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \
+#if ! _GLIBCXX_USE_CXX11_ABI \
+    && defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED)	\
     && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \
     && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
 
@@ -525,7 +527,7 @@ _GLIBCXX_MATHL_WRAPPER1 (tan, GLIBCXX_3.4);
 #endif
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
 
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
 extern void *_ZTVN10__cxxabiv123__fundamental_type_infoE[];
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
 
-#ifdef _GLIBCXX_USE_NLS
+# ifdef _GLIBCXX_USE_NLS
 #  include <libintl.h>
 #  define _(msgid)   gettext (msgid)
-#else
+# else
 #  define _(msgid)   (msgid)
-#endif
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-10-07 12:25         ` François Dumont
@ 2023-10-07 19:32           ` François Dumont
  2023-10-09 14:42             ` Iain Sandoe
  2023-10-24  4:55             ` François Dumont
  0 siblings, 2 replies; 20+ messages in thread
From: François Dumont @ 2023-10-07 19:32 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Jonathan Wakely, libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 12773 bytes --]

I've been told that previous patch generated with 'git diff -b' was not 
applying properly so here is the same patch again with a simple 'git diff'.


On 07/10/2023 14:25, François Dumont wrote:
> Hi
>
> Here is a rebased version of this patch.
>
> There are few test failures when running 'make check-c++' but nothing 
> new.
>
> Still, there are 2 patches awaiting validation to fix some of them, PR 
> c++/111524 to fix another bunch and I fear that we will have to live 
> with the others.
>
>     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>
>     Use cxx11 abi when activating versioned namespace mode. To do support
>     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
> _GLIBCXX_USE_CXX11_ABI.
>
>     The main change is that std::__cow_string is now defined whenever 
> _GLIBCXX_USE_DUAL_ABI
>     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
> available std::string in
>     case of dual abi and a subset of it when it's not.
>
>     On the other side std::__sso_string is defined only when 
> _GLIBCXX_USE_DUAL_ABI is true
>     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
> std::__sso_string is a typedef for the
>     cow std::string implementation when dual abi is disabled and cow 
> string is being used.
>
>     libstdcxx-v3/ChangeLog:
>
>             PR libstdc++/83077
>             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
> Default to "new" libstdcxx abi
>             when enable_symvers is gnu-versioned-namespace.
>             * config/locale/dragonfly/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>             members.
>             * config/locale/generic/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>             * config/locale/gnu/monetary_members.cc 
> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>             * config/locale/gnu/numeric_members.cc
>             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>             * configure: Regenerate.
>             * include/bits/c++config
>             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
> _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>             Define empty.
> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
> _GLIBCXX_DEFAULT_ABI_TAG):
>             Likewise.
>             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
> Define a light version of COW
>             basic_string as __std_cow_string for use in stdexcept.
>             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
> __cow_string.
>             (__cow_string(const char*)): New.
>             (__cow_string::c_str()): New.
>             * python/libstdcxx/v6/printers.py 
> (StdStringPrinter::__init__): Set self.new_string to True
>             when std::__8::basic_string type is found.
>             * src/Makefile.am 
> [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
>             * src/Makefile.in: Regenerate.
>             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
> cxx11-hash_tr1.cc,
>             cxx11-ios_failure.cc entries to...
>             (sources): ...this.
>             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
> cow-sstream-inst.cc, cow-string-inst.cc,
>             cow-string-io-inst.cc, cow-wtring-inst.cc, 
> cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>             cxx11-wlocale-inst.cc entries to...
>             (inst_sources): ...this.
>             * src/c++11/Makefile.in: Regenerate.
>             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Include <bits/cow_string.h>.
>             [_GLIBCXX_USE_DUAL_ABI || 
> _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>             including <stdexcept>. Define 
> _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>             __cow_string definition in <stdexcept> is skipped.
>             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
> definitions.
>             * src/c++11/string-inst.cc: Add sizeof/alignof 
> static_assert on stdexcept
>             __cow_string definition.
>             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
> following _GLIBCXX_USE_CXX11_ABI
>             value.
>             [_GLIBCXX_USE_CXX11_ABI && 
> !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
> Include <bits/cow_string.h>.
>             Define basic_string as __std_cow_string for the current 
> translation unit.
>             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-string-io-inst.cc 
> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cow-wstring-io-inst.cc 
> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cxx11-ios_failure.cc 
> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
> locale-inst.cc.
>             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++11/cxx11-wlocale-inst.cc 
> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++11/locale-inst-numeric.h
> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
> std::use_facet<num_put<>>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
> std::has_facet<num_put<>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
> istreambuf_iterator<C>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
> ostreambuf_iterator<C>>): Instantiate.
>             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
> only when configured
>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
> ostreambuf_iterator<C>>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
> ostreambuf_iterator<C>>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
> mbstate_t>): Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
> mbstate_t>): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
> mbstate_t>>(const locale&)): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
> mbstate_t>>(const locale&)): Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
> Instantiate.
> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
> Instantiate.
>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
> const C*,
>             ios_base::fmtflags, bool)): Define.
>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
> long, const C*,
>             ios_base::fmtflags, bool)): Define.
>             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: 
> Skip definitions.
>             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, 
> unique cow-istream-string.cc entry
>             move to...
>             (inst_sources): ...this.
>             * src/c++98/Makefile.in: Regenerate.
>             * src/c++98/cow-istream-string.cc: Include 
> <bits/c++config.h>.
>             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
> definitions.
>             * src/c++98/ios_failure.cc 
> [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
> Build only when configured
>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>             * src/c++98/locale_facets.cc 
> [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>             * src/c++98/stdexcept.cc
>             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): 
> Remove.
>             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
> Remove.
>             * src/c++98/compatibility.cc [_GLIBCXX_USE_CXX11_ABI]: 
> Skip all definitions appart from
>             istream::ignore(streamsize).
>
> Tested under Linux x64_86, ok to commit ?
>
> François
>
>
> On 17/08/2023 19:22, Jonathan Wakely wrote:
>> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
>> <libstdc++@gcc.gnu.org> wrote:
>>> Here is the fixed patch tested in all 3 modes:
>>>
>>> - _GLIBCXX_USE_DUAL_ABI
>>>
>>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>>
>>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>>
>>> I don't know what you have in mind for the change below but I wanted to
>>> let you know that I tried to put COW std::basic_string into a nested
>>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>>> string-inst.cc so I preferred the macro substitution approach.
>> I was thinking of implementing the necessary special members functions
>> of __cow_string directly, so they are ABI compatible with the COW
>> std::basic_string but don't actually reuse the code. That would mean
>> we don't need to compile and instantiate the whole COW string just to
>> use a few members from it. But that can be done later, the macro
>> approach seems OK for now.
>>
>>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>>> unrelated with my changes. I'll propose fixes in coming days.
>> Which tests? I run the entire testsuite with
>> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
>> failures.
>>
>> I'll review the patch ASAP, thanks for working on it.
>>

[-- Attachment #2: cxx11_gnu-versioned-ns.patch --]
[-- Type: text/x-patch, Size: 60568 bytes --]

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index d8f0ba1c3e2..793471216e6 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     AC_MSG_NOTICE([dual ABI is disabled])
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      AC_MSG_NOTICE([dual ABI is disabled])
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
   GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes)
 ])
diff --git a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
index f534bbe4aeb..3f96f2b9f11 100644
--- a/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/monetary_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 2c1cfeff094..a1ae136be04 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 1f46ea2f53f..87561bcc821 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -37,7 +37,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // This file might be compiled twice, but we only want to define the members
 // of money_base once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   // Construct and return valid pattern consisting of some combination of:
   // space none symbol sign value
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return __ret;
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index 220a0f8c510..cb8095e6ac7 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
 
 // This file might be compiled twice, but we only want to define this once.
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   char
   __narrow_multibyte_chars(const char* s, __locale_t cloc)
   {
@@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     return '\0';
   }
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 
   template<>
     void
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 13fc03b2a3f..58e01f7d16f 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -70702,13 +70702,18 @@ fi
 
 
   if test x$enable_symvers = xgnu-versioned-namespace; then
-    # gnu-versioned-namespace is incompatible with the dual ABI.
-    enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+    # gnu-versioned-namespace is incompatible with the dual ABI...
     { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
 $as_echo "$as_me: dual ABI is disabled" >&6;}
-    default_libstdcxx_abi="gcc4-compatible"
+    enable_libstdcxx_dual_abi="no"
+    # ... and use the cxx11 one.
+    default_libstdcxx_abi="new"
+  else
+    if test x"$enable_libstdcxx_dual_abi" != xyes; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5
+$as_echo "$as_me: dual ABI is disabled" >&6;}
+      default_libstdcxx_abi="gcc4-compatible"
+    fi
   fi
 
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 410c136e1b1..3367179c1c3 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -337,26 +337,6 @@ namespace std
 #define _GLIBCXX_USE_CXX11_ABI
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI
-namespace std
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-namespace __gnu_cxx
-{
-  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
-}
-# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
-# define _GLIBCXX_END_NAMESPACE_CXX11 }
-# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
-#else
-# define _GLIBCXX_NAMESPACE_CXX11
-# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
-# define _GLIBCXX_END_NAMESPACE_CXX11
-# define _GLIBCXX_DEFAULT_ABI_TAG
-#endif
-
 // Non-zero if inline namespaces are used for versioning the entire library.
 #define _GLIBCXX_INLINE_VERSION 
 
@@ -415,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Non-inline namespace for components replaced by alternates in active mode.
   namespace __cxx1998
   {
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
   inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
 # endif
   }
@@ -445,6 +425,26 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # endif
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_INLINE_VERSION
+namespace std
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+namespace __gnu_cxx
+{
+  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
+}
+# define _GLIBCXX_NAMESPACE_CXX11 __cxx11::
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 {
+# define _GLIBCXX_END_NAMESPACE_CXX11 }
+# define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11
+#else
+# define _GLIBCXX_NAMESPACE_CXX11
+# define _GLIBCXX_BEGIN_NAMESPACE_CXX11
+# define _GLIBCXX_END_NAMESPACE_CXX11
+# define _GLIBCXX_DEFAULT_ABI_TAG
+#endif
+
 // Macros for namespace scope. Either namespace std:: or the name
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index 5411dfe32a9..702d59faefe 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -32,13 +32,15 @@
 #ifndef _COW_STRING_H
 #define _COW_STRING_H 1
 
-#if ! _GLIBCXX_USE_CXX11_ABI
-
 #include <ext/atomicity.h> // _Atomic_word, __is_single_threaded
 
 #define __glibcxx_want_constexpr_string
 #include <bits/version.h>
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define basic_string __std_cow_string
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -830,6 +832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       end() const _GLIBCXX_NOEXCEPT
       { return const_iterator(_M_data() + this->size()); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns a read/write reverse iterator that points to the last
        *  character in the %string.  Iteration is done in reverse element
@@ -901,6 +904,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->begin()); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     public:
       // Capacity:
@@ -928,6 +932,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       max_size() const _GLIBCXX_NOEXCEPT
       { return _Rep::_S_max_size; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Resizes the %string to the specified number of characters.
        *  @param  __n  Number of characters the %string should contain.
@@ -1007,6 +1012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__resize_and_overwrite(size_type __n, _Operation __op);
 #endif
 
+#endif // ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  Returns the total number of characters that the %string can hold
        *  before needing to allocate more memory.
@@ -1015,6 +1021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       capacity() const _GLIBCXX_NOEXCEPT
       { return _M_rep()->_M_capacity; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Attempt to preallocate enough memory for specified number of
        *          characters.
@@ -1063,6 +1070,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       clear()
       { _M_mutate(0, this->size(), 0); }
 #endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  Returns true if the %string is empty.  Equivalent to
@@ -1072,6 +1080,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       empty() const _GLIBCXX_NOEXCEPT
       { return this->size() == 0; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       // Element access:
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -1382,6 +1391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	traits_type::assign(_M_data()[this->size()], __c);
 	_M_rep()->_M_set_length_and_sharable(__len);
       }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
       /**
        *  @brief  Set value to contents of another string.
@@ -1526,6 +1536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 #endif // C++17
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Insert multiple characters.
        *  @param __p  Iterator referencing location in string to insert at.
@@ -2144,6 +2155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return this->replace(__i1 - begin(), __i2 - __i1, __sv);
 	}
 #endif // C++17
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
     private:
       template<class _Integer>
@@ -2215,6 +2227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     public:
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Copy substring into C string.
        *  @param __s  C string to copy value into.
@@ -2229,6 +2242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       size_type
       copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
+#endif
 
       /**
        *  @brief  Swap contents with another string.
@@ -2286,6 +2300,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return _M_dataplus; }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
       /**
        *  @brief  Find position of a C substring.
        *  @param __s  C string to locate.
@@ -3091,6 +3106,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       contains(const _CharT* __x) const noexcept
       { return __sv_type(this->data(), this->size()).contains(__x); }
 #endif // C++23
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 # ifdef _GLIBCXX_TM_TS_INTERNAL
       friend void
@@ -3294,6 +3310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
      }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3457,6 +3474,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
 	 }
      }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3518,6 +3536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_set_length_and_sharable(__new_size);
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3543,6 +3562,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_rep()->_M_dispose(__a);
       _M_data(__tmp);
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
@@ -3666,6 +3686,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __r->_M_refdata();
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3679,6 +3700,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	this->erase(__n);
       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
     }
+#endif
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
@@ -3719,6 +3741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     basic_string<_CharT, _Traits, _Alloc>::
@@ -3800,8 +3823,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 #endif // C++11
 
-
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif  // ! _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI
+# undef basic_string
+#endif
 #endif  // _COW_STRING_H
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 66c8572d0cd..33306508695 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -42,8 +42,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if _GLIBCXX_USE_DUAL_ABI
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
   // Emulates an old COW string when the new std::string is in use.
   struct __cow_string
   {
@@ -54,6 +54,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     __cow_string();
     __cow_string(const std::string&);
+    __cow_string(const char*);
     __cow_string(const char*, size_t);
     __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
     __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
@@ -62,12 +63,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __cow_string(__cow_string&&) noexcept;
     __cow_string& operator=(__cow_string&&) noexcept;
 #endif
+    const char* c_str() const _GLIBCXX_NOEXCEPT;
   };
-
-  typedef basic_string<char> __sso_string;
-#else // _GLIBCXX_USE_CXX11_ABI
+#endif // ! _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
+#else
   typedef basic_string<char> __cow_string;
+#endif
 
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
   // Emulates a new SSO string when the old std::string is in use.
   struct __sso_string
   {
@@ -94,10 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __sso_string& operator=(__sso_string&&) noexcept;
 #endif
   };
-#endif // _GLIBCXX_USE_CXX11_ABI
-#else  // _GLIBCXX_USE_DUAL_ABI
+#else
   typedef basic_string<char> __sso_string;
-  typedef basic_string<char> __cow_string;
 #endif
 
   /**
@@ -127,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(logic_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     logic_error(const logic_error&) _GLIBCXX_NOTHROW;
     logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
@@ -233,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(runtime_error&&) noexcept;
 #endif
 
-#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
+#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS
     runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
     runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
 #elif __cplusplus >= 201103L
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 7e16a49aeb0..81785a6e66b 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1029,6 +1029,8 @@ class StdStringPrinter(printer_base):
     def __init__(self, typename, val):
         self._val = val
         self._new_string = typename.find("::__cxx11::basic_string") != -1
+        if not self._new_string:
+            self._new_string = typename.find("::" + _versioned_namespace + "basic_string") != -1
 
     def to_string(self):
         # Make sure &string works, too.
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 32de5304122..16f46faf91a 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -91,6 +91,9 @@ else
 ldbl_compat_sources =
 endif
 
+if ENABLE_SYMVERS_GNU_NAMESPACE
+ldbl_alt128_compat_sources =
+else
 if GLIBCXX_LDBL_ALT128_COMPAT
 if ENABLE_DUAL_ABI
 ldbl_alt128_compat_cxx11_sources = \
@@ -104,6 +107,7 @@ ldbl_alt128_compat_sources = \
 else
 ldbl_alt128_compat_sources =
 endif
+endif
 
 if ENABLE_SYMVERS_GNU_NAMESPACE
 cxx0x_compat_sources =
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index c5d01e7beba..17618c278bc 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -157,10 +157,9 @@ am__objects_2 = compatibility.lo compatibility-debug_list.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-chrono.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-condvar.lo \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-thread-c++0x.lo
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 =  \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.lo \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_4 = compatibility-ldbl-alt128-cxx11.lo
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@am__objects_5 = compatibility-ldbl-alt128.lo \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	$(am__objects_4)
 am__objects_6 = $(am__objects_3) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libstdc___la_OBJECTS = $(am__objects_2) \
 @GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
@@ -512,14 +511,15 @@ SUBDIRS = c++98 c++11 c++17 c++20 c++23 \
 
 @GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources = 
 @GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
-@ENABLE_DUAL_ABI_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
-@ENABLE_DUAL_ABI_TRUE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
-
-@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
-@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@ldbl_alt128_compat_sources = 
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_sources = \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128.cc \
+@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	${ldbl_alt128_compat_cxx11_sources}
+
+@ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@ldbl_alt128_compat_sources = 
+@ENABLE_DUAL_ABI_FALSE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = 
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ldbl_alt128_compat_cxx11_sources = \
+@ENABLE_DUAL_ABI_TRUE@@ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@	compatibility-ldbl-alt128-cxx11.cc
 
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@cxx0x_compat_sources = \
 @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@	compatibility-atomic-c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 9cddb978928..be8e35754b8 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -48,15 +48,11 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
 if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-locale_init.cc \
+dual_abi_sources = \
 	cow-shim_facets.cc \
-	cxx11-hash_tr1.cc \
-	cxx11-ios_failure.cc \
-	cxx11-shim_facets.cc \
-	cxx11-stdexcept.cc
+	cxx11-shim_facets.cc
 else
-cxx11_abi_sources =
+dual_abi_sources =
 endif
 
 sources_freestanding = \
@@ -68,8 +64,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -88,20 +88,12 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
 if ENABLE_DUAL_ABI
 extra_string_inst_sources = \
-	cow-fstream-inst.cc \
-	cow-sstream-inst.cc \
-	cow-string-inst.cc \
-	cow-string-io-inst.cc \
-	cow-wstring-inst.cc \
-	cow-wstring-io-inst.cc \
-	cxx11-locale-inst.cc \
-	cxx11-wlocale-inst.cc \
 	sso_string.cc
 else
 extra_string_inst_sources =
@@ -111,6 +103,14 @@ if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 inst_sources = \
 	$(extra_string_inst_sources) \
+	cow-fstream-inst.cc \
+	cow-sstream-inst.cc \
+	cow-string-inst.cc \
+	cow-string-io-inst.cc \
+	cow-wstring-inst.cc \
+	cow-wstring-io-inst.cc \
+	cxx11-locale-inst.cc \
+	cxx11-wlocale-inst.cc \
 	ext11-inst.cc \
 	fstream-inst.cc \
 	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index e6d37c5464c..171ff1adf16 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -122,27 +122,28 @@ CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = limits.lo placeholders.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-locale_init.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.lo cxx11-hash_tr1.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
+@ENABLE_DUAL_ABI_TRUE@am__objects_2 = cow-shim_facets.lo \
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo
 am__objects_3 = ctype_configure_char.lo ctype_members.lo
 am__objects_4 = basic_file.lo
 am__objects_5 = assert_fail.lo chrono.lo codecvt.lo \
-	condition_variable.lo cow-stdexcept.lo ctype.lo debug.lo \
-	functexcept.lo functional.lo futex.lo future.lo hash_c++0x.lo \
-	hashtable_c++0x.lo ios.lo ios_errcat.lo locale_init.lo \
-	localename.lo mutex.lo random.lo regex.lo shared_ptr.lo \
-	snprintf_lite.lo system_error.lo thread.lo $(am__objects_2) \
-	$(am__objects_3) $(am__objects_4)
-@ENABLE_DUAL_ABI_TRUE@am__objects_6 = cow-fstream-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.lo cow-string-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.lo \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.lo sso_string.lo
+	condition_variable.lo cow-locale_init.lo cow-stdexcept.lo \
+	ctype.lo cxx11-hash_tr1.lo cxx11-ios_failure.lo \
+	cxx11-stdexcept.lo debug.lo functexcept.lo functional.lo \
+	futex.lo future.lo hash_c++0x.lo hashtable_c++0x.lo ios.lo \
+	ios_errcat.lo locale_init.lo localename.lo mutex.lo random.lo \
+	regex.lo shared_ptr.lo snprintf_lite.lo system_error.lo \
+	thread.lo $(am__objects_2) $(am__objects_3) $(am__objects_4)
+@ENABLE_DUAL_ABI_TRUE@am__objects_6 = sso_string.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_7 = $(am__objects_6) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.lo fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.lo iostream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	istream-inst.lo locale-inst.lo \
@@ -469,14 +470,10 @@ host_sources = \
 host_sources_extra = \
 	basic_file.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-locale_init.cc \
+@ENABLE_DUAL_ABI_FALSE@dual_abi_sources = 
+@ENABLE_DUAL_ABI_TRUE@dual_abi_sources = \
 @ENABLE_DUAL_ABI_TRUE@	cow-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-hash_tr1.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-ios_failure.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-stdexcept.cc
+@ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.cc
 
 sources_freestanding = \
 	limits.cc \
@@ -487,8 +484,12 @@ sources = \
 	chrono.cc \
 	codecvt.cc \
 	condition_variable.cc \
+	cow-locale_init.cc \
 	cow-stdexcept.cc \
 	ctype.cc \
+	cxx11-hash_tr1.cc \
+	cxx11-ios_failure.cc \
+	cxx11-stdexcept.cc \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
@@ -507,20 +508,12 @@ sources = \
 	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc \
-	${cxx11_abi_sources} \
+	${dual_abi_sources} \
 	${host_sources} \
 	${host_sources_extra}
 
 @ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = 
 @ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-fstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-sstream-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-string-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cow-wstring-io-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-locale-inst.cc \
-@ENABLE_DUAL_ABI_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_DUAL_ABI_TRUE@	sso_string.cc
 
 # XTEMPLATE_FLAGS =
@@ -529,6 +522,14 @@ sources = \
 # XTEMPLATE_FLAGS = -fno-implicit-templates
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	$(extra_string_inst_sources) \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-fstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-sstream-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-string-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cow-wstring-io-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-locale-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	cxx11-wlocale-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ext11-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	ios-inst.cc \
diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
index 0562bc6c9cb..8153387daea 100644
--- a/libstdc++-v3/src/c++11/cow-fstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <fstream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -76,3 +73,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc
index f48561f5b12..bfe1d19db04 100644
--- a/libstdc++-v3/src/c++11/cow-locale_init.cc
+++ b/libstdc++-v3/src/c++11/cow-locale_init.cc
@@ -24,10 +24,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <locale>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -166,6 +163,7 @@ namespace
 #endif
   }
 
+#if _GLIBCXX_USE_DUAL_ABI
 // TODO should be in another file
   string
   locale::name() const
@@ -191,6 +189,8 @@ namespace
       }
     return __ret;
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
index 035a267d9d8..7699170d13d 100644
--- a/libstdc++-v3/src/c++11/cow-sstream-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc
@@ -27,8 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "sstream-inst.cc"
+#include <bits/c++config.h>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "sstream-inst.cc"
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 8d1cc4605d4..23f853eadac 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -43,11 +43,52 @@ _txnal_runtime_error_get_msg(void* e);
 
 // All exception classes still use the classic COW std::string.
 #define _GLIBCXX_USE_CXX11_ABI 0
-#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
-#define __cow_string __cow_stringxxx
+#include <string>
+
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI
+#  include <bits/cow_string.h>
+# endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+# if _GLIBCXX_USE_CXX11_ABI
+  typedef std::__std_cow_string<char, std::char_traits<char>,
+				std::allocator<char>> cowstr;
+# else
+  typedef std::string cowstr;
+# endif
+
+  // Redefine __cow_string so that we can define and export its members
+  // in terms of the COW std::string.
+  struct __cow_string
+  {
+    union {
+      const char* _M_p;
+      char _M_bytes[sizeof(_M_p)];
+      cowstr _M_str;
+    };
+
+    __cow_string();
+    __cow_string(const std::string& s);
+    __cow_string(const char*);
+    __cow_string(const char*, size_t);
+    __cow_string(const __cow_string&) noexcept;
+    __cow_string& operator=(const __cow_string&) noexcept;
+    ~__cow_string();
+    __cow_string(__cow_string&&) noexcept;
+    __cow_string& operator=(__cow_string&&) noexcept;
+    const char* c_str() const noexcept;
+  };
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif
+
+#define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS 1
 #include <stdexcept>
 #include <system_error>
-#undef __cow_string
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -114,30 +155,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Converting constructor from COW std::string to SSO string.
   __sso_string::__sso_string(const string& s)
   : __sso_string(s.c_str(), s.length()) { }
+#endif
 
-  // Redefine __cow_string so that we can define and export its members
-  // in terms of the COW std::string.
-  struct __cow_string
-  {
-    union {
-      const char* _M_p;
-      char _M_bytes[sizeof(_M_p)];
-      std::string _M_str;
-    };
-
-    __cow_string();
-    __cow_string(const std::string& s);
-    __cow_string(const char*, size_t n);
-    __cow_string(const __cow_string&) noexcept;
-    __cow_string& operator=(const __cow_string&) noexcept;
-    ~__cow_string();
-    __cow_string(__cow_string&&) noexcept;
-    __cow_string& operator=(__cow_string&&) noexcept;
-  };
-
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string() : _M_str() { }
 
+#if !_GLIBCXX_USE_CXX11_ABI
   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
+#endif
+
+  __cow_string::__cow_string(const char* s) : _M_str(s) { }
 
   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
 
@@ -151,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  __cow_string::~__cow_string() { _M_str.~basic_string(); }
+  __cow_string::~__cow_string() { _M_str.~cowstr(); }
 
   __cow_string::__cow_string(__cow_string&& s) noexcept
   : _M_str(std::move(s._M_str)) { }
@@ -163,12 +190,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return *this;
   }
 
-  static_assert(sizeof(__cow_string) == sizeof(std::string),
+  const char*
+  __cow_string::c_str() const noexcept
+  { return _M_str.c_str(); }
+
+  static_assert(sizeof(__cow_string) == sizeof(cowstr),
                 "sizeof(std::string) has changed");
-  static_assert(alignof(__cow_string) == alignof(std::string),
+  static_assert(alignof(__cow_string) == alignof(cowstr),
                 "alignof(std::string) has changed");
-#endif
+#endif // _GLIBCXX_USE_CXX11_ABI
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   // Return error_category::message() as an SSO string
   __sso_string
   error_category::_M_message(int i) const
@@ -176,10 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     string msg = this->message(i);
     return {msg.c_str(), msg.length()};
   }
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 // Support for the Transactional Memory TS (N4514).
 //
 // logic_error and runtime_error both carry a message in the form of a COW
@@ -463,3 +497,4 @@ CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
 
 #endif  // _GLIBCXX_USE_C99_STDINT
 #endif  // _GLIBCXX_USE_WEAK_REF
+#endif  // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc
index 5a2b8ffa568..57c28129f00 100644
--- a/libstdc++-v3/src/c++11/cow-string-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-inst.cc
@@ -29,10 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include "string-inst.cc"
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if _GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
 #include <random>
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -45,3 +42,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
   random_device::_M_init_pretr1(const std::string& token)
   { _M_init(token.c_str(), token.length()); }
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-string-io-inst.cc b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
index 505bc9dd384..9abc9b47e52 100644
--- a/libstdc++-v3/src/c++11/cow-string-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-string-io-inst.cc
@@ -30,10 +30,7 @@
 #include <istream>
 #include <ostream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -57,3 +54,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
index ce533ea8fa5..d3c3b0c297e 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc
@@ -29,12 +29,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #define C wchar_t
 #include "string-inst.cc"
-
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
 #endif
-
 #endif
diff --git a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
index 49394b0e275..0e6cc490fa4 100644
--- a/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
+++ b/libstdc++-v3/src/c++11/cow-wstring-io-inst.cc
@@ -29,14 +29,11 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 #ifdef _GLIBCXX_USE_WCHAR_T
 #include <ostream>
 #include <istream>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
-
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -61,3 +58,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif
+#endif
diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
index 22a7685eeca..0b9fc28ceaa 100644
--- a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
+++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc
@@ -25,9 +25,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <string>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 #include <tr1/functional>
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -57,3 +55,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
index e0e816b453b..46bfda329de 100644
--- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
+++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc
@@ -38,9 +38,7 @@
 # define _(msgid)   (msgid)
 #endif
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -62,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   ios_base::failure::what() const throw()
   { return runtime_error::what(); }
 
-#if __cpp_rtti
+#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
   // These functions are defined in src/c++98/ios_failure.cc
   extern void __construct_ios_failure(void*, const char*);
   extern void __destroy_ios_failure(void*);
@@ -118,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     // Otherwise proceed as normal to see if the handler matches.
     return __class_type_info::__do_upcast(dst_type, obj_ptr);
   }
-#else // ! __cpp_rtti
+#else // ! _GLIBCXX_USE_DUAL_ABI || ! __cpp_rtti
   using __ios_failure = ios::failure;
 #endif
 
@@ -136,3 +134,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
index 94b181886d3..e21cc5548bf 100644
--- a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc
@@ -27,11 +27,5 @@
 // Facet instantiations using new ABI strings.
 
 #define _GLIBCXX_USE_CXX11_ABI 1
-#include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#define C char
-#define C_is_char
-# include "locale-inst.cc"
+#include "locale-inst.cc"
diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
index 74c070c0439..38ab35692a3 100644
--- a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc
@@ -29,9 +29,7 @@
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <stdexcept>
 
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
+#if _GLIBCXX_USE_CXX11_ABI
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -76,3 +74,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
index 11fb15d9602..faff236c1df 100644
--- a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc
@@ -28,11 +28,10 @@
 
 #define _GLIBCXX_USE_CXX11_ABI 1
 #include <bits/c++config.h>
-#if ! _GLIBCXX_USE_DUAL_ABI
-# error This file should not be compiled for this configuration.
-#endif
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
+#if _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif
 #endif
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index b917fe5802e..211e19c7ff9 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -30,7 +30,7 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 // use_facet and has_facet instantiations
 INSTANTIATE_FACET_ACCESSORS(num_get<C>);
 INSTANTIATE_FACET_ACCESSORS(num_put<C>);
@@ -38,7 +38,7 @@ INSTANTIATE_FACET_ACCESSORS(num_put<C>);
 
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class num_get<C, istreambuf_iterator<C> >;
   template class num_put<C, ostreambuf_iterator<C> >;
 #endif
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 		   unsigned long long&) const;
 #endif
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // num_put member function templates
   template
     ostreambuf_iterator<C>
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index 3a5c6844f1b..ee3375d7040 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -35,8 +35,17 @@
 # define _GLIBCXX_USE_CXX11_ABI 0
 #endif
 
-#include <locale>
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
 
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
+
+#include <locale>
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -52,7 +61,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // moneypunct, money_get, and money_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __moneypunct_cache<C, false>;
   template struct __moneypunct_cache<C, true>;
 #endif
@@ -64,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // numpunct, numpunct_byname, num_get, and num_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template struct __numpunct_cache<C>;
 #endif
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -73,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
   // time_get and time_put
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template class __timepunct<C>;
   template struct __timepunct_cache<C>;
   template class time_put<C, ostreambuf_iterator<C> >;
@@ -97,13 +106,13 @@ _GLIBCXX_END_NAMESPACE_CXX11
   ctype_byname<C>::ctype_byname(const string& __s, size_t __refs)
   : ctype_byname(__s.c_str(), __refs) { }
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __ctype_abstract_base<C>;
   template class ctype_byname<C>;
 #endif
 
   // codecvt
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   inline template class __codecvt_abstract_base<C, char, mbstate_t>;
   template class codecvt_byname<C, char, mbstate_t>;
 #else
@@ -118,7 +127,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_CXX11
 
 // use_facet and has_facet instantiations
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(ctype<C>);
 INSTANTIATE_FACET_ACCESSORS(codecvt<C, char, mbstate_t>);
 #endif
@@ -127,14 +136,14 @@ INSTANTIATE_FACET_ACCESSORS(numpunct<C>);
 INSTANTIATE_FACET_ACCESSORS(moneypunct<C, false>);
 // No explicit instantiation of has_facet<moneypunct<C, true>> for some reason.
 INSTANTIATE_USE_FACET      (moneypunct<C, true>);
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
 INSTANTIATE_FACET_ACCESSORS(__timepunct<C>);
 INSTANTIATE_FACET_ACCESSORS(time_put<C>);
 #endif
 INSTANTIATE_FACET_ACCESSORS(time_get<C>);
 INSTANTIATE_FACET_ACCESSORS(messages<C>);
 
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   // locale functions.
   template
     C*
@@ -163,3 +172,5 @@ _GLIBCXX_END_NAMESPACE_VERSION
 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && ! _GLIBCXX_USE_CXX11_ABI
 #include "compatibility-ldbl-facets-aliases.h"
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+
+#endif //  _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc
index ddaafc08199..f29176dfc88 100644
--- a/libstdc++-v3/src/c++11/string-inst.cc
+++ b/libstdc++-v3/src/c++11/string-inst.cc
@@ -35,6 +35,12 @@
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
 
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 1
+#else
+# define _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS 0
+#endif
+
 // Prevent the basic_string(const _CharT*, const _Alloc&) and
 // basic_string(size_type, _CharT, const _Alloc&) constructors from being
 // replaced by constrained function templates, so that we instantiate the
@@ -45,6 +51,29 @@
 
 #include <string>
 
+#if _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+#include <stdexcept>
+
+#if _GLIBCXX_USE_CXX11_ABI
+# include <bits/cow_string.h>
+typedef std::__std_cow_string<char, std::char_traits<char>,
+			      std::allocator<char>> cowstr;
+#else
+typedef std::string cowstr;
+#endif
+
+static_assert(sizeof(std::__cow_string) == sizeof(cowstr),
+	      "sizeof(std::string) has changed");
+static_assert(alignof(std::__cow_string) == alignof(cowstr),
+	      "alignof(std::string) has changed");
+#endif // _GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI
+
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS
+# define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS 1
+# include <bits/cow_string.h>
+# define basic_string __std_cow_string
+#endif
+
 // Instantiation configuration.
 #ifndef C
 # define C char
@@ -54,12 +83,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  typedef basic_string<C> S;
+typedef basic_string<C, std::char_traits<C>, std::allocator<C>> S;
 
-  template class basic_string<C>;
+  template class basic_string<C, std::char_traits<C>, std::allocator<C>>;
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
+#endif
 
   // Only one template keyword allowed here.
   // See core issue #46 (NAD)
@@ -73,7 +104,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
     S::basic_string(S::iterator, S::iterator, const allocator<C>&);
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
   template
     void
     S::_M_construct(S::iterator, S::iterator, forward_iterator_tag);
@@ -91,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     S::_M_construct(const C*, const C*, forward_iterator_tag);
 
-#else // !_GLIBCXX_USE_CXX11_ABI
+#else // ! _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 
   template
     C*
@@ -111,6 +142,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
+#if ! _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -121,3 +153,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif
diff --git a/libstdc++-v3/src/c++11/wlocale-inst.cc b/libstdc++-v3/src/c++11/wlocale-inst.cc
index dc2d2349055..b5c798bfe64 100644
--- a/libstdc++-v3/src/c++11/wlocale-inst.cc
+++ b/libstdc++-v3/src/c++11/wlocale-inst.cc
@@ -30,7 +30,9 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#ifdef _GLIBCXX_USE_WCHAR_T
-#define C wchar_t
-#include "locale-inst.cc"
-#endif // _GLIBCXX_USE_WCHAR_T
+#if ! _GLIBCXX_USE_CXX11_ABI
+# ifdef _GLIBCXX_USE_WCHAR_T
+#  define C wchar_t
+#  include "locale-inst.cc"
+# endif // _GLIBCXX_USE_WCHAR_T
+#endif
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 72be2d2d2ea..86242397d33 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -86,12 +86,8 @@ host_sources_extra = \
 c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CLOCALE_CC) ./$@ || true
 
-if ENABLE_DUAL_ABI
-cxx11_abi_sources = \
-	cow-istream-string.cc
-else
-cxx11_abi_sources =
-endif
+basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
+	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
 
 if ENABLE_EXTERN_TEMPLATE
 # XTEMPLATE_FLAGS = -fno-implicit-templates
@@ -114,6 +110,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -136,7 +133,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra} \
 	${inst_sources} \
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 95e909b1049..761fbcf6135 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -121,30 +121,29 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__98convenience_la_LIBADD =
-@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo
-@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \
+@ENABLE_DUAL_ABI_TRUE@am__objects_1 = collate_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	messages_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	monetary_members_cow.lo \
 @ENABLE_DUAL_ABI_TRUE@	numeric_members_cow.lo
-am__objects_3 = $(am__objects_2) codecvt_members.lo collate_members.lo \
+am__objects_2 = $(am__objects_1) codecvt_members.lo collate_members.lo \
 	messages_members.lo monetary_members.lo numeric_members.lo \
 	time_members.lo
-am__objects_4 = c++locale.lo
-@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_5 = allocator-inst.lo \
+am__objects_3 = c++locale.lo
+@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	concept-inst.lo ext-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	misc-inst.lo
-am__objects_6 = parallel_settings.lo
-am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
-	codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \
-	hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \
-	list.lo list-aux.lo list-aux-2.lo list_associated.lo \
-	list_associated-2.lo locale.lo locale_facets.lo \
-	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
-	strstream.lo tree.lo istream.lo istream-string.lo streambuf.lo \
-	valarray.lo $(am__objects_1) $(am__objects_3) $(am__objects_4) \
-	$(am__objects_5) $(am__objects_6)
+am__objects_5 = parallel_settings.lo
+am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+	codecvt.lo complex_io.lo cow-istream-string.lo globals_io.lo \
+	hash_tr1.lo hashtable_tr1.lo ios_failure.lo ios_init.lo \
+	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
+	list_associated.lo list_associated-2.lo locale.lo \
+	locale_facets.lo math_stubs_float.lo math_stubs_long_double.lo \
+	stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \
+	streambuf.lo valarray.lo $(am__objects_2) $(am__objects_3) \
+	$(am__objects_4) $(am__objects_5)
 @GLIBCXX_HOSTED_TRUE@am_libc__98convenience_la_OBJECTS =  \
-@GLIBCXX_HOSTED_TRUE@	$(am__objects_7)
+@GLIBCXX_HOSTED_TRUE@	$(am__objects_6)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -469,10 +468,6 @@ host_sources = \
 host_sources_extra = \
 	c++locale.cc
 
-@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = 
-@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \
-@ENABLE_DUAL_ABI_TRUE@	cow-istream-string.cc
-
 # XTEMPLATE_FLAGS =
 @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = 
 
@@ -492,6 +487,7 @@ sources = \
 	mt_allocator.cc \
 	codecvt.cc \
 	complex_io.cc \
+	cow-istream-string.cc \
 	globals_io.cc \
 	hash_tr1.cc \
 	hashtable_tr1.cc \
@@ -514,7 +510,6 @@ sources = \
 	istream-string.cc \
 	streambuf.cc \
 	valarray.cc \
-	${cxx11_abi_sources} \
 	${host_sources} \
 	${host_sources_extra} \
 	${inst_sources} \
@@ -869,6 +864,9 @@ time_members.cc: ${glibcxx_srcdir}/$(CTIME_CC)
 c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
 	$(LN_S) ${glibcxx_srcdir}/$(CLOCALE_CC) ./$@ || true
 
+basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
+	$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
+
 vpath % $(top_srcdir)/src/c++98
 
 # Use special rules to compile with -fimplicit-templates.
diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc
index 5ff21f09c43..b7feae2649d 100644
--- a/libstdc++-v3/src/c++98/compatibility.cc
+++ b/libstdc++-v3/src/c++98/compatibility.cc
@@ -25,7 +25,8 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <bits/c++config.h>
 
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \
+#if ! _GLIBCXX_USE_CXX11_ABI \
+    && defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED)	\
     && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE)\
     && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
 #define istreambuf_iterator istreambuf_iteratorXX
@@ -220,7 +221,8 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 // NB: These symbols renames should go into the shared library only,
 // and only those shared libraries that support versioning.
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \
+#if ! _GLIBCXX_USE_CXX11_ABI \
+    && defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED)	\
     && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \
     && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
 
@@ -525,7 +527,7 @@ _GLIBCXX_MATHL_WRAPPER1 (tan, GLIBCXX_3.4);
 #endif
 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
 
-#endif
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
 extern void *_ZTVN10__cxxabiv123__fundamental_type_infoE[];
diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc
index 405f9ecb781..f00cbc09f69 100644
--- a/libstdc++-v3/src/c++98/cow-istream-string.cc
+++ b/libstdc++-v3/src/c++98/cow-istream-string.cc
@@ -27,4 +27,8 @@
 //
 
 #define _GLIBCXX_USE_CXX11_ABI 0
-#include "istream-string.cc"
+#include <bits/c++config.h>
+
+#if ! _GLIBCXX_USE_CXX11_ABI
+# include "istream-string.cc"
+#endif
diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc
index e132c01bf8e..a2cd2c509f3 100644
--- a/libstdc++-v3/src/c++98/hash_tr1.cc
+++ b/libstdc++-v3/src/c++98/hash_tr1.cc
@@ -28,6 +28,7 @@
 
 #include "hash-long-double-tr1-aux.cc"
 
+#if ! _GLIBCXX_USE_CXX11_ABI
 namespace std _GLIBCXX_VISIBILITY(default)
 {
   namespace tr1
@@ -57,3 +58,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
 #endif
   }
 }
+#endif // ! _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc
index 27476eccbdb..43291871196 100644
--- a/libstdc++-v3/src/c++98/ios_failure.cc
+++ b/libstdc++-v3/src/c++98/ios_failure.cc
@@ -29,22 +29,24 @@
 #define _GLIBCXX_USE_CXX11_ABI 0
 #include <ios>
 
-#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
-#include <cxxabi.h>
-#include <typeinfo>
-#endif
-
-#ifdef _GLIBCXX_USE_NLS
-# include <libintl.h>
-# define _(msgid)   gettext (msgid)
-#else
-# define _(msgid)   (msgid)
-#endif
+#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+# if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti
+#  include <cxxabi.h>
+#  include <typeinfo>
+# endif
+
+# ifdef _GLIBCXX_USE_NLS
+#  include <libintl.h>
+#  define _(msgid)   gettext (msgid)
+# else
+#  define _(msgid)   (msgid)
+# endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   ios_base::failure::failure(const string& __str) throw()
   : _M_msg(__str) { }
 
@@ -54,6 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const char*
   ios_base::failure::what() const throw()
   { return _M_msg.c_str(); }
+#endif
 
 #if _GLIBCXX_USE_DUAL_ABI
   // When the dual ABI is enabled __throw_ios_failure() is defined in
@@ -82,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif // __cpp_rtti
 
-#else // ! _GLIBCXX_USE_DUAL_ABI
+#elif ! _GLIBCXX_USE_CXX11_ABI
 
   void
   __throw_ios_failure(const char* __s __attribute__((unused)))
@@ -92,7 +95,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_ios_failure(const char* str, int)
   { __throw_ios_failure(str); }
 
-#endif // _GLIBCXX_USE_DUAL_ABI
+#endif // ! _GLIBCXX_USE_CXX11_ABI
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#endif // ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc
index 4859987fcc2..b64347f796e 100644
--- a/libstdc++-v3/src/c++98/istream-string.cc
+++ b/libstdc++-v3/src/c++98/istream-string.cc
@@ -31,6 +31,16 @@
 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
 # define _GLIBCXX_USE_CXX11_ABI 1
 #endif
+
+#if _GLIBCXX_USE_CXX11_ABI
+# define _GLIBCXX_BUILD_CXX11_ABI 1
+#else
+# define _GLIBCXX_BUILD_CXX11_ABI 0
+#endif
+
+#include <bits/c++config.h>
+
+#if _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
 #include <istream>
 #include <string>
 
@@ -289,3 +299,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+#endif // _GLIBCXX_BUILD_CXX11_ABI == _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc
index c0bb7fd181d..7a929d51be4 100644
--- a/libstdc++-v3/src/c++98/locale_facets.cc
+++ b/libstdc++-v3/src/c++98/locale_facets.cc
@@ -125,6 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __test;
   }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   bool
   __verify_grouping(const char* __grouping, size_t __grouping_size,
 		    const string& __grouping_tmp) throw()
@@ -133,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                   __grouping_tmp.c_str(),
                                   __grouping_tmp.size());
   }
+#endif
 
   namespace
   {
diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc
index e8c91f5c1cd..e82554e0aec 100644
--- a/libstdc++-v3/src/c++98/stdexcept.cc
+++ b/libstdc++-v3/src/c++98/stdexcept.cc
@@ -35,8 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -44,28 +46,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   logic_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
+#endif
 
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
+#endif
 
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
@@ -73,18 +85,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   runtime_error::what() const _GLIBCXX_USE_NOEXCEPT
   { return _M_msg.c_str(); }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
+#if ! _GLIBCXX_USE_CXX11_ABI
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
+#endif
 
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-10-07 19:32           ` François Dumont
@ 2023-10-09 14:42             ` Iain Sandoe
  2023-10-09 16:27               ` Iain Sandoe
  2023-10-09 17:38               ` François Dumont
  2023-10-24  4:55             ` François Dumont
  1 sibling, 2 replies; 20+ messages in thread
From: Iain Sandoe @ 2023-10-09 14:42 UTC (permalink / raw)
  To: François Dumont
  Cc: Jonathan Wakely, Jonathan Wakely, libstdc++, GCC Patches

Hi François,

> On 7 Oct 2023, at 20:32, François Dumont <frs.dumont@gmail.com> wrote:
> 
> I've been told that previous patch generated with 'git diff -b' was not applying properly so here is the same patch again with a simple 'git diff'.

Thanks, that did fix it - There are some training whitespaces in the config files, but I suspect that they need to be there since those have values appended during the configuration.

Anyway, with this + the coroutines and contract v2 (weak def) fix, plus a local patch to enable versioned namespace on Darwin, I get results comparable with the non-versioned case - but one more patchlet is needed on  yours (to allow for targets using emultated TLS):

diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index 9fab8bead15..b7167fc0c2f 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -78,6 +78,7 @@ GLIBCXX_8.0 {
 
     # thread/mutex/condition_variable/future
     __once_proxy;
+    __emutls_v._ZNSt3__81?__once_call*;
 
     # std::__convert_to_v
     _ZNSt3__814__convert_to_v*;


thanks
Iain

> 
> 
> On 07/10/2023 14:25, François Dumont wrote:
>> Hi
>> 
>> Here is a rebased version of this patch.
>> 
>> There are few test failures when running 'make check-c++' but nothing new.
>> 
>> Still, there are 2 patches awaiting validation to fix some of them, PR c++/111524 to fix another bunch and I fear that we will have to live with the others.
>> 
>>     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>> 
>>     Use cxx11 abi when activating versioned namespace mode. To do support
>>     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and _GLIBCXX_USE_CXX11_ABI.
>> 
>>     The main change is that std::__cow_string is now defined whenever _GLIBCXX_USE_DUAL_ABI
>>     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using available std::string in
>>     case of dual abi and a subset of it when it's not.
>> 
>>     On the other side std::__sso_string is defined only when _GLIBCXX_USE_DUAL_ABI is true
>>     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that std::__sso_string is a typedef for the
>>     cow std::string implementation when dual abi is disabled and cow string is being used.
>> 
>>     libstdcxx-v3/ChangeLog:
>> 
>>             PR libstdc++/83077
>>             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default to "new" libstdcxx abi
>>             when enable_symvers is gnu-versioned-namespace.
>>             * config/locale/dragonfly/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>             members.
>>             * config/locale/generic/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>             * config/locale/gnu/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>             * config/locale/gnu/numeric_members.cc
>>             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>             * configure: Regenerate.
>>             * include/bits/c++config
>>             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>             Define empty.
>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, _GLIBCXX_DEFAULT_ABI_TAG):
>>             Likewise.
>>             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: Define a light version of COW
>>             basic_string as __std_cow_string for use in stdexcept.
>>             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define __cow_string.
>>             (__cow_string(const char*)): New.
>>             (__cow_string::c_str()): New.
>>             * python/libstdcxx/v6/printers.py (StdStringPrinter::__init__): Set self.new_string to True
>>             when std::__8::basic_string type is found.
>>             * src/Makefile.am [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
>>             * src/Makefile.in: Regenerate.
>>             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>>             (dual_abi_sources): ...this. Also move cow-local_init.cc, cxx11-hash_tr1.cc,
>>             cxx11-ios_failure.cc entries to...
>>             (sources): ...this.
>>             (extra_string_inst_sources): Move cow-fstream-inst.cc, cow-sstream-inst.cc, cow-string-inst.cc,
>>             cow-string-io-inst.cc, cow-wtring-inst.cc, cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>             cxx11-wlocale-inst.cc entries to...
>>             (inst_sources): ...this.
>>             * src/c++11/Makefile.in: Regenerate.
>>             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: Include <bits/cow_string.h>.
>>             [_GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>>             including <stdexcept>. Define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>>             __cow_string definition in <stdexcept> is skipped.
>>             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS definitions.
>>             * src/c++11/string-inst.cc: Add sizeof/alignof static_assert on stdexcept
>>             __cow_string definition.
>>             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following _GLIBCXX_USE_CXX11_ABI
>>             value.
>>             [_GLIBCXX_USE_CXX11_ABI && !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. Include <bits/cow_string.h>.
>>             Define basic_string as __std_cow_string for the current translation unit.
>>             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-wstring-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include locale-inst.cc.
>>             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cxx11-wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/locale-inst-numeric.h
>> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, std::use_facet<num_put<>>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, std::has_facet<num_put<>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, istreambuf_iterator<C>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, ostreambuf_iterator<C>>): Instantiate.
>>             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build only when configured
>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, ostreambuf_iterator<C>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, ostreambuf_iterator<C>>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, mbstate_t>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, mbstate_t>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, mbstate_t>>(const locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, mbstate_t>>(const locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, const C*,
>>             ios_base::fmtflags, bool)): Define.
>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long long, const C*,
>>             ios_base::fmtflags, bool)): Define.
>>             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, unique cow-istream-string.cc entry
>>             move to...
>>             (inst_sources): ...this.
>>             * src/c++98/Makefile.in: Regenerate.
>>             * src/c++98/cow-istream-string.cc: Include <bits/c++config.h>.
>>             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++98/ios_failure.cc [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: Build only when configured
>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>             * src/c++98/locale_facets.cc [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>             * src/c++98/stdexcept.cc
>>             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): Remove.
>>             * src/c++98/compatibility.cc [_GLIBCXX_USE_CXX11_ABI]: Skip all definitions appart from
>>             istream::ignore(streamsize).
>> 
>> Tested under Linux x64_86, ok to commit ?
>> 
>> François
>> 
>> 
>> On 17/08/2023 19:22, Jonathan Wakely wrote:
>>> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
>>> <libstdc++@gcc.gnu.org> wrote:
>>>> Here is the fixed patch tested in all 3 modes:
>>>> 
>>>> - _GLIBCXX_USE_DUAL_ABI
>>>> 
>>>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>>> 
>>>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>>> 
>>>> I don't know what you have in mind for the change below but I wanted to
>>>> let you know that I tried to put COW std::basic_string into a nested
>>>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>>>> string-inst.cc so I preferred the macro substitution approach.
>>> I was thinking of implementing the necessary special members functions
>>> of __cow_string directly, so they are ABI compatible with the COW
>>> std::basic_string but don't actually reuse the code. That would mean
>>> we don't need to compile and instantiate the whole COW string just to
>>> use a few members from it. But that can be done later, the macro
>>> approach seems OK for now.
>>> 
>>>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>>>> unrelated with my changes. I'll propose fixes in coming days.
>>> Which tests? I run the entire testsuite with
>>> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
>>> failures.
>>> 
>>> I'll review the patch ASAP, thanks for working on it.
> <cxx11_gnu-versioned-ns.patch>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-10-09 14:42             ` Iain Sandoe
@ 2023-10-09 16:27               ` Iain Sandoe
  2023-10-09 17:38               ` François Dumont
  1 sibling, 0 replies; 20+ messages in thread
From: Iain Sandoe @ 2023-10-09 16:27 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: François Dumont, Jonathan Wakely, libstdc++, GCC Patches



> On 9 Oct 2023, at 15:42, Iain Sandoe <idsandoe@googlemail.com> wrote:

>> On 7 Oct 2023, at 20:32, François Dumont <frs.dumont@gmail.com> wrote:
>> 
>> I've been told that previous patch generated with 'git diff -b' was not applying properly so here is the same patch again with a simple 'git diff'.
> 
> Thanks, that did fix it - There are some training whitespaces in the config files, but I suspect that they need to be there since those have values appended during the configuration.
> 
> Anyway, with this + the coroutines and contract v2 (weak def) fix, plus a local patch to enable versioned namespace on Darwin, I get results comparable with the non-versioned case - but one more patchlet is needed on  yours (to allow for targets using emultated TLS):
> 
> diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
> index 9fab8bead15..b7167fc0c2f 100644
> --- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
> +++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
> @@ -78,6 +78,7 @@ GLIBCXX_8.0 {
> 
>     # thread/mutex/condition_variable/future
>     __once_proxy;
> +    __emutls_v._ZNSt3__81?__once_call*;
> 
>     # std::__convert_to_v
>     _ZNSt3__814__convert_to_v*;

Having said this, since the versioned lib is an ABI-break, perhaps we should also take the opportunity
to fix the once_call impl. here too?

(at least the fix I made locally does not need the TLS var, so ths would then be moot)

Iain

> 
> thanks
> Iain
> 
>> 
>> 
>> On 07/10/2023 14:25, François Dumont wrote:
>>> Hi
>>> 
>>> Here is a rebased version of this patch.
>>> 
>>> There are few test failures when running 'make check-c++' but nothing new.
>>> 
>>> Still, there are 2 patches awaiting validation to fix some of them, PR c++/111524 to fix another bunch and I fear that we will have to live with the others.
>>> 
>>>    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>> 
>>>    Use cxx11 abi when activating versioned namespace mode. To do support
>>>    a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and _GLIBCXX_USE_CXX11_ABI.
>>> 
>>>    The main change is that std::__cow_string is now defined whenever _GLIBCXX_USE_DUAL_ABI
>>>    or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using available std::string in
>>>    case of dual abi and a subset of it when it's not.
>>> 
>>>    On the other side std::__sso_string is defined only when _GLIBCXX_USE_DUAL_ABI is true
>>>    and _GLIBCXX_USE_CXX11_ABI is false. Meaning that std::__sso_string is a typedef for the
>>>    cow std::string implementation when dual abi is disabled and cow string is being used.
>>> 
>>>    libstdcxx-v3/ChangeLog:
>>> 
>>>            PR libstdc++/83077
>>>            * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default to "new" libstdcxx abi
>>>            when enable_symvers is gnu-versioned-namespace.
>>>            * config/locale/dragonfly/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>>            members.
>>>            * config/locale/generic/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>            * config/locale/gnu/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>            * config/locale/gnu/numeric_members.cc
>>>            [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>>            * configure: Regenerate.
>>>            * include/bits/c++config
>>>            [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>>            Define empty.
>>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, _GLIBCXX_DEFAULT_ABI_TAG):
>>>            Likewise.
>>>            * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: Define a light version of COW
>>>            basic_string as __std_cow_string for use in stdexcept.
>>>            * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define __cow_string.
>>>            (__cow_string(const char*)): New.
>>>            (__cow_string::c_str()): New.
>>>            * python/libstdcxx/v6/printers.py (StdStringPrinter::__init__): Set self.new_string to True
>>>            when std::__8::basic_string type is found.
>>>            * src/Makefile.am [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
>>>            * src/Makefile.in: Regenerate.
>>>            * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>>>            (dual_abi_sources): ...this. Also move cow-local_init.cc, cxx11-hash_tr1.cc,
>>>            cxx11-ios_failure.cc entries to...
>>>            (sources): ...this.
>>>            (extra_string_inst_sources): Move cow-fstream-inst.cc, cow-sstream-inst.cc, cow-string-inst.cc,
>>>            cow-string-io-inst.cc, cow-wtring-inst.cc, cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>>            cxx11-wlocale-inst.cc entries to...
>>>            (inst_sources): ...this.
>>>            * src/c++11/Makefile.in: Regenerate.
>>>            * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: Include <bits/cow_string.h>.
>>>            [_GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>>>            including <stdexcept>. Define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>>>            __cow_string definition in <stdexcept> is skipped.
>>>            [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS definitions.
>>>            * src/c++11/string-inst.cc: Add sizeof/alignof static_assert on stdexcept
>>>            __cow_string definition.
>>>            (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following _GLIBCXX_USE_CXX11_ABI
>>>            value.
>>>            [_GLIBCXX_USE_CXX11_ABI && !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>>            Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. Include <bits/cow_string.h>.
>>>            Define basic_string as __std_cow_string for the current translation unit.
>>>            * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cow-wstring-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>>            * src/c++11/cxx11-locale-inst.cc: Cleanup, just include locale-inst.cc.
>>>            * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/cxx11-wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++11/locale-inst-numeric.h
>>> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, std::use_facet<num_put<>>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, std::has_facet<num_put<>>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, istreambuf_iterator<C>>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, ostreambuf_iterator<C>>): Instantiate.
>>>            * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build only when configured
>>>            _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](time_put<C, ostreambuf_iterator<C>>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, ostreambuf_iterator<C>>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, mbstate_t>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, mbstate_t>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, mbstate_t>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, mbstate_t>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): Instantiate.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, const C*,
>>>            ios_base::fmtflags, bool)): Define.
>>>            [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long long, const C*,
>>>            ios_base::fmtflags, bool)): Define.
>>>            * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++98/Makefile.am (cxx11_abi_sources): Remove, unique cow-istream-string.cc entry
>>>            move to...
>>>            (inst_sources): ...this.
>>>            * src/c++98/Makefile.in: Regenerate.
>>>            * src/c++98/cow-istream-string.cc: Include <bits/c++config.h>.
>>>            [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>            * src/c++98/ios_failure.cc [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>>            * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: Build only when configured
>>>            _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>>            * src/c++98/locale_facets.cc [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>>            * src/c++98/stdexcept.cc
>>>            [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): Remove.
>>>            [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): Remove.
>>>            * src/c++98/compatibility.cc [_GLIBCXX_USE_CXX11_ABI]: Skip all definitions appart from
>>>            istream::ignore(streamsize).
>>> 
>>> Tested under Linux x64_86, ok to commit ?
>>> 
>>> François
>>> 
>>> 
>>> On 17/08/2023 19:22, Jonathan Wakely wrote:
>>>> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
>>>> <libstdc++@gcc.gnu.org> wrote:
>>>>> Here is the fixed patch tested in all 3 modes:
>>>>> 
>>>>> - _GLIBCXX_USE_DUAL_ABI
>>>>> 
>>>>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>>>> 
>>>>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>>>> 
>>>>> I don't know what you have in mind for the change below but I wanted to
>>>>> let you know that I tried to put COW std::basic_string into a nested
>>>>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>>>>> string-inst.cc so I preferred the macro substitution approach.
>>>> I was thinking of implementing the necessary special members functions
>>>> of __cow_string directly, so they are ABI compatible with the COW
>>>> std::basic_string but don't actually reuse the code. That would mean
>>>> we don't need to compile and instantiate the whole COW string just to
>>>> use a few members from it. But that can be done later, the macro
>>>> approach seems OK for now.
>>>> 
>>>>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>>>>> unrelated with my changes. I'll propose fixes in coming days.
>>>> Which tests? I run the entire testsuite with
>>>> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
>>>> failures.
>>>> 
>>>> I'll review the patch ASAP, thanks for working on it.
>> <cxx11_gnu-versioned-ns.patch>
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-10-09 14:42             ` Iain Sandoe
  2023-10-09 16:27               ` Iain Sandoe
@ 2023-10-09 17:38               ` François Dumont
  1 sibling, 0 replies; 20+ messages in thread
From: François Dumont @ 2023-10-09 17:38 UTC (permalink / raw)
  To: Iain Sandoe; +Cc: Jonathan Wakely, Jonathan Wakely, libstdc++, GCC Patches


On 09/10/2023 16:42, Iain Sandoe wrote:
> Hi François,
>
>> On 7 Oct 2023, at 20:32, François Dumont <frs.dumont@gmail.com> wrote:
>>
>> I've been told that previous patch generated with 'git diff -b' was not applying properly so here is the same patch again with a simple 'git diff'.
> Thanks, that did fix it - There are some training whitespaces in the config files, but I suspect that they need to be there since those have values appended during the configuration.

You're talking about the ones coming from regenerated Makefile.in and 
configure I guess. I prefer not to edit those, those trailing 
whitespaces are already in.


>
> Anyway, with this + the coroutines and contract v2 (weak def) fix, plus a local patch to enable versioned namespace on Darwin, I get results comparable with the non-versioned case - but one more patchlet is needed on  yours (to allow for targets using emultated TLS):
>
> diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
> index 9fab8bead15..b7167fc0c2f 100644
> --- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
> +++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
> @@ -78,6 +78,7 @@ GLIBCXX_8.0 {
>   
>       # thread/mutex/condition_variable/future
>       __once_proxy;
> +    __emutls_v._ZNSt3__81?__once_call*;

I can add this one, sure, even if it could be part of a dedicated patch. 
I'm surprised that we do not need the __once_callable emul symbol too, 
it would be more consistent with the non-versioned mode.

I'm pretty sure there are a bunch of other symbols missing, but this 
mode is seldomly tested...

>   
>       # std::__convert_to_v
>       _ZNSt3__814__convert_to_v*;
>
>
> thanks
> Iain
>
>>
>> On 07/10/2023 14:25, François Dumont wrote:
>>> Hi
>>>
>>> Here is a rebased version of this patch.
>>>
>>> There are few test failures when running 'make check-c++' but nothing new.
>>>
>>> Still, there are 2 patches awaiting validation to fix some of them, PR c++/111524 to fix another bunch and I fear that we will have to live with the others.
>>>
>>>      libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>>
>>>      Use cxx11 abi when activating versioned namespace mode. To do support
>>>      a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and _GLIBCXX_USE_CXX11_ABI.
>>>
>>>      The main change is that std::__cow_string is now defined whenever _GLIBCXX_USE_DUAL_ABI
>>>      or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using available std::string in
>>>      case of dual abi and a subset of it when it's not.
>>>
>>>      On the other side std::__sso_string is defined only when _GLIBCXX_USE_DUAL_ABI is true
>>>      and _GLIBCXX_USE_CXX11_ABI is false. Meaning that std::__sso_string is a typedef for the
>>>      cow std::string implementation when dual abi is disabled and cow string is being used.
>>>
>>>      libstdcxx-v3/ChangeLog:
>>>
>>>              PR libstdc++/83077
>>>              * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default to "new" libstdcxx abi
>>>              when enable_symvers is gnu-versioned-namespace.
>>>              * config/locale/dragonfly/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>>              members.
>>>              * config/locale/generic/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>              * config/locale/gnu/monetary_members.cc [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>>              * config/locale/gnu/numeric_members.cc
>>>              [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>>              * configure: Regenerate.
>>>              * include/bits/c++config
>>>              [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>>              Define empty.
>>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, _GLIBCXX_DEFAULT_ABI_TAG):
>>>              Likewise.
>>>              * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: Define a light version of COW
>>>              basic_string as __std_cow_string for use in stdexcept.
>>>              * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define __cow_string.
>>>              (__cow_string(const char*)): New.
>>>              (__cow_string::c_str()): New.
>>>              * python/libstdcxx/v6/printers.py (StdStringPrinter::__init__): Set self.new_string to True
>>>              when std::__8::basic_string type is found.
>>>              * src/Makefile.am [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
>>>              * src/Makefile.in: Regenerate.
>>>              * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>>>              (dual_abi_sources): ...this. Also move cow-local_init.cc, cxx11-hash_tr1.cc,
>>>              cxx11-ios_failure.cc entries to...
>>>              (sources): ...this.
>>>              (extra_string_inst_sources): Move cow-fstream-inst.cc, cow-sstream-inst.cc, cow-string-inst.cc,
>>>              cow-string-io-inst.cc, cow-wtring-inst.cc, cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>>              cxx11-wlocale-inst.cc entries to...
>>>              (inst_sources): ...this.
>>>              * src/c++11/Makefile.in: Regenerate.
>>>              * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: Include <bits/cow_string.h>.
>>>              [_GLIBCXX_USE_DUAL_ABI || _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>>>              including <stdexcept>. Define _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>>>              __cow_string definition in <stdexcept> is skipped.
>>>              [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS definitions.
>>>              * src/c++11/string-inst.cc: Add sizeof/alignof static_assert on stdexcept
>>>              __cow_string definition.
>>>              (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define following _GLIBCXX_USE_CXX11_ABI
>>>              value.
>>>              [_GLIBCXX_USE_CXX11_ABI && !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>>              Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. Include <bits/cow_string.h>.
>>>              Define basic_string as __std_cow_string for the current translation unit.
>>>              * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cow-wstring-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>>              * src/c++11/cxx11-locale-inst.cc: Cleanup, just include locale-inst.cc.
>>>              * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/cxx11-wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++11/locale-inst-numeric.h
>>> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, std::use_facet<num_put<>>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, std::has_facet<num_put<>>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, istreambuf_iterator<C>>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, ostreambuf_iterator<C>>): Instantiate.
>>>              * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build only when configured
>>>              _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](time_put<C, ostreambuf_iterator<C>>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, ostreambuf_iterator<C>>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, mbstate_t>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, mbstate_t>): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, mbstate_t>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, mbstate_t>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): Instantiate.
>>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): Instantiate.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, const C*,
>>>              ios_base::fmtflags, bool)): Define.
>>>              [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long long, const C*,
>>>              ios_base::fmtflags, bool)): Define.
>>>              * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++98/Makefile.am (cxx11_abi_sources): Remove, unique cow-istream-string.cc entry
>>>              move to...
>>>              (inst_sources): ...this.
>>>              * src/c++98/Makefile.in: Regenerate.
>>>              * src/c++98/cow-istream-string.cc: Include <bits/c++config.h>.
>>>              [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>>              * src/c++98/ios_failure.cc [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>>              * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: Build only when configured
>>>              _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>>              * src/c++98/locale_facets.cc [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>>              * src/c++98/stdexcept.cc
>>>              [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): Remove.
>>>              [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): Remove.
>>>              * src/c++98/compatibility.cc [_GLIBCXX_USE_CXX11_ABI]: Skip all definitions appart from
>>>              istream::ignore(streamsize).
>>>
>>> Tested under Linux x64_86, ok to commit ?
>>>
>>> François
>>>
>>>
>>> On 17/08/2023 19:22, Jonathan Wakely wrote:
>>>> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
>>>> <libstdc++@gcc.gnu.org> wrote:
>>>>> Here is the fixed patch tested in all 3 modes:
>>>>>
>>>>> - _GLIBCXX_USE_DUAL_ABI
>>>>>
>>>>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>>>>
>>>>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>>>>
>>>>> I don't know what you have in mind for the change below but I wanted to
>>>>> let you know that I tried to put COW std::basic_string into a nested
>>>>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>>>>> string-inst.cc so I preferred the macro substitution approach.
>>>> I was thinking of implementing the necessary special members functions
>>>> of __cow_string directly, so they are ABI compatible with the COW
>>>> std::basic_string but don't actually reuse the code. That would mean
>>>> we don't need to compile and instantiate the whole COW string just to
>>>> use a few members from it. But that can be done later, the macro
>>>> approach seems OK for now.
>>>>
>>>>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>>>>> unrelated with my changes. I'll propose fixes in coming days.
>>>> Which tests? I run the entire testsuite with
>>>> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
>>>> failures.
>>>>
>>>> I'll review the patch ASAP, thanks for working on it.
>> <cxx11_gnu-versioned-ns.patch>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]
  2023-10-07 19:32           ` François Dumont
  2023-10-09 14:42             ` Iain Sandoe
@ 2023-10-24  4:55             ` François Dumont
  1 sibling, 0 replies; 20+ messages in thread
From: François Dumont @ 2023-10-24  4:55 UTC (permalink / raw)
  To: libstdc++; +Cc: gcc-patches

Hi

Still no one to complete this review ?

Thanks


On 07/10/2023 21:32, François Dumont wrote:
> I've been told that previous patch generated with 'git diff -b' was 
> not applying properly so here is the same patch again with a simple 
> 'git diff'.
>
>
> On 07/10/2023 14:25, François Dumont wrote:
>> Hi
>>
>> Here is a rebased version of this patch.
>>
>> There are few test failures when running 'make check-c++' but nothing 
>> new.
>>
>> Still, there are 2 patches awaiting validation to fix some of them, 
>> PR c++/111524 to fix another bunch and I fear that we will have to 
>> live with the others.
>>
>>     libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]
>>
>>     Use cxx11 abi when activating versioned namespace mode. To do 
>> support
>>     a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
>> _GLIBCXX_USE_CXX11_ABI.
>>
>>     The main change is that std::__cow_string is now defined whenever 
>> _GLIBCXX_USE_DUAL_ABI
>>     or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
>> available std::string in
>>     case of dual abi and a subset of it when it's not.
>>
>>     On the other side std::__sso_string is defined only when 
>> _GLIBCXX_USE_DUAL_ABI is true
>>     and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
>> std::__sso_string is a typedef for the
>>     cow std::string implementation when dual abi is disabled and cow 
>> string is being used.
>>
>>     libstdcxx-v3/ChangeLog:
>>
>>             PR libstdc++/83077
>>             * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
>> Default to "new" libstdcxx abi
>>             when enable_symvers is gnu-versioned-namespace.
>>             * config/locale/dragonfly/monetary_members.cc 
>> [!_GLIBCXX_USE_DUAL_ABI]: Define money_base
>>             members.
>>             * config/locale/generic/monetary_members.cc 
>> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>             * config/locale/gnu/monetary_members.cc 
>> [!_GLIBCXX_USE_DUAL_ABI]: Likewise.
>>             * config/locale/gnu/numeric_members.cc
>>             [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
>>             * configure: Regenerate.
>>             * include/bits/c++config
>>             [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
>> _GLIBCXX_BEGIN_NAMESPACE_CXX11):
>>             Define empty.
>> [_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
>> _GLIBCXX_DEFAULT_ABI_TAG):
>>             Likewise.
>>             * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
>> Define a light version of COW
>>             basic_string as __std_cow_string for use in stdexcept.
>>             * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
>> __cow_string.
>>             (__cow_string(const char*)): New.
>>             (__cow_string::c_str()): New.
>>             * python/libstdcxx/v6/printers.py 
>> (StdStringPrinter::__init__): Set self.new_string to True
>>             when std::__8::basic_string type is found.
>>             * src/Makefile.am 
>> [ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define 
>> empty.
>>             * src/Makefile.in: Regenerate.
>>             * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
>>             (dual_abi_sources): ...this. Also move cow-local_init.cc, 
>> cxx11-hash_tr1.cc,
>>             cxx11-ios_failure.cc entries to...
>>             (sources): ...this.
>>             (extra_string_inst_sources): Move cow-fstream-inst.cc, 
>> cow-sstream-inst.cc, cow-string-inst.cc,
>>             cow-string-io-inst.cc, cow-wtring-inst.cc, 
>> cow-wstring-io-inst.cc, cxx11-locale-inst.cc,
>>             cxx11-wlocale-inst.cc entries to...
>>             (inst_sources): ...this.
>>             * src/c++11/Makefile.in: Regenerate.
>>             * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Include <bits/cow_string.h>.
>>             [_GLIBCXX_USE_DUAL_ABI || 
>> _GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
>>             including <stdexcept>. Define 
>> _GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that
>>             __cow_string definition in <stdexcept> is skipped.
>>             [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
>> definitions.
>>             * src/c++11/string-inst.cc: Add sizeof/alignof 
>> static_assert on stdexcept
>>             __cow_string definition.
>>             (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
>> following _GLIBCXX_USE_CXX11_ABI
>>             value.
>>             [_GLIBCXX_USE_CXX11_ABI && 
>> !_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
>>             Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
>> Include <bits/cow_string.h>.
>>             Define basic_string as __std_cow_string for the current 
>> translation unit.
>>             * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-string-io-inst.cc 
>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cow-wstring-io-inst.cc 
>> [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cxx11-ios_failure.cc 
>> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
>>             * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
>> locale-inst.cc.
>>             * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++11/cxx11-wlocale-inst.cc 
>> [!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++11/locale-inst-numeric.h
>> [!_GLIBCXX_USE_DUAL_ABI](std::use_facet<num_get<>>, 
>> std::use_facet<num_put<>>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](std::has_facet<num_get<>>, 
>> std::has_facet<num_put<>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_get<C, 
>> istreambuf_iterator<C>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](std::num_put<C, 
>> ostreambuf_iterator<C>>): Instantiate.
>>             * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: 
>> Build only when configured
>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, false>): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache<C, true>): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__timepunct<C>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](time_put<C, 
>> ostreambuf_iterator<C>>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](time_put_byname<C, 
>> ostreambuf_iterator<C>>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base<C>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](ctype_byname<C>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](__codecvt_abstract_base<C, char, 
>> mbstate_t>): Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](codecvt_byname<C, char, 
>> mbstate_t>): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<ctype<C>>(const locale&)): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](use_facet<codecvt<C, char, 
>> mbstate_t>>(const locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<__timepunct<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](use_facet<time_put<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<ctype<C>>(const locale&)): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](has_facet<codecvt<C, char, 
>> mbstate_t>>(const locale&)): Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<__timepunct<C>>(const locale&)): 
>> Instantiate.
>> [!_GLIBCXX_USE_DUAL_ABI](has_facet<time_put<C>>(const locale&)): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__add_grouping<C>): Define.
>>             [!_GLIBCXX_USE_DUAL_ABI](__pad<C, char_traits<C>>): 
>> Instantiate.
>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long, 
>> const C*,
>>             ios_base::fmtflags, bool)): Define.
>>             [!_GLIBCXX_USE_DUAL_ABI](__int_to_char(C*, unsigned long 
>> long, const C*,
>>             ios_base::fmtflags, bool)): Define.
>>             * src/c++11/wlocale-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: 
>> Skip definitions.
>>             * src/c++98/Makefile.am (cxx11_abi_sources): Remove, 
>> unique cow-istream-string.cc entry
>>             move to...
>>             (inst_sources): ...this.
>>             * src/c++98/Makefile.in: Regenerate.
>>             * src/c++98/cow-istream-string.cc: Include 
>> <bits/c++config.h>.
>>             [_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
>>             * src/c++98/hash_tr1.cc [_GLIBCXX_USE_CXX11_ABI]: Skip 
>> definitions.
>>             * src/c++98/ios_failure.cc 
>> [_GLIBCXX_USE_CXX11_ABI][_GLIBCXX_USE_DUAL_ABI]: Skip definitions.
>>             * src/c++98/istream-string.cc [!_GLIBCXX_USE_DUAL_ABI]: 
>> Build only when configured
>>             _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
>>             * src/c++98/locale_facets.cc 
>> [_GLIBCXX_USE_CXX11_ABI](__verify_grouping): Remove.
>>             * src/c++98/stdexcept.cc
>>             [_GLIBCXX_USE_CXX11_ABI](logic_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](domain_error(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](invalid_argument(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](length_error(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](out_of_range(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](runtime_error(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](range_error(const string&): Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](overflow_error(const string&): 
>> Remove.
>>             [_GLIBCXX_USE_CXX11_ABI](underflow_error(const string&): 
>> Remove.
>>             * src/c++98/compatibility.cc [_GLIBCXX_USE_CXX11_ABI]: 
>> Skip all definitions appart from
>>             istream::ignore(streamsize).
>>
>> Tested under Linux x64_86, ok to commit ?
>>
>> François
>>
>>
>> On 17/08/2023 19:22, Jonathan Wakely wrote:
>>> On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
>>> <libstdc++@gcc.gnu.org> wrote:
>>>> Here is the fixed patch tested in all 3 modes:
>>>>
>>>> - _GLIBCXX_USE_DUAL_ABI
>>>>
>>>> - !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI
>>>>
>>>> - !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI
>>>>
>>>> I don't know what you have in mind for the change below but I 
>>>> wanted to
>>>> let you know that I tried to put COW std::basic_string into a nested
>>>> __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
>>>> string-inst.cc so I preferred the macro substitution approach.
>>> I was thinking of implementing the necessary special members functions
>>> of __cow_string directly, so they are ABI compatible with the COW
>>> std::basic_string but don't actually reuse the code. That would mean
>>> we don't need to compile and instantiate the whole COW string just to
>>> use a few members from it. But that can be done later, the macro
>>> approach seems OK for now.
>>>
>>>> There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
>>>> unrelated with my changes. I'll propose fixes in coming days.
>>> Which tests? I run the entire testsuite with
>>> -D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
>>> failures.
>>>
>>> I'll review the patch ASAP, thanks for working on it.
>>>

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2023-10-24  4:55 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-10  5:13 [PATCH] sso-string@gnu-versioned-namespace [PR83077] François Dumont
2023-08-11  5:43 ` François Dumont
2023-08-11  7:51   ` Jonathan Wakely
2023-08-13 13:27     ` François Dumont
2023-08-13 19:51       ` François Dumont
2023-08-17 17:17         ` François Dumont
2023-08-24 17:33           ` François Dumont
2023-08-17 17:22       ` Jonathan Wakely
2023-08-17 17:40         ` François Dumont
2023-08-17 18:59           ` Jonathan Wakely
2023-08-17 19:37             ` Jonathan Wakely
2023-08-17 19:44               ` Jonathan Wakely
2023-08-17 23:31                 ` Jonathan Wakely
2023-08-19 19:44                 ` François Dumont
2023-10-07 12:25         ` François Dumont
2023-10-07 19:32           ` François Dumont
2023-10-09 14:42             ` Iain Sandoe
2023-10-09 16:27               ` Iain Sandoe
2023-10-09 17:38               ` François Dumont
2023-10-24  4:55             ` François Dumont

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).