diff mbox

[v2] libstdc++: Make certain exceptions transaction_safe.

Message ID 1452185238.26597.230.camel@localhost.localdomain
State New
Headers show

Commit Message

Torvald Riegel Jan. 7, 2016, 4:47 p.m. UTC
The attached patch makes some exceptions transaction-safe, as require by
the Transactional Memory TS.  I believe I addressed all feedback for the
previous version of this patch (in particular, there are now more safety
checks for preconditions for this implementation (eg, that the new
allocator is used), all exceptions declared by the TM TS are now
supported (with the exception of tx_exception -- should I add that in a
follow-up patch?), and there is a test for the new functionality (as
part of libitm's testsuite)).

There are two things that complicate such support.  First, it seems
better to not rely on -fgnu-tm of libstdc++ code for now (or at least we
tried to avoid this so far).  Therefore, the transactional clones in
this patch are all manually instrumented (ie, the functions are C
functions with names matching the mangled names of the respective C++
functions, and the _ZGTt prefix signaling that they are txnal clones).

Second, exceptions still use a COW string internally, which cannot be
made transaction-safe with just compiler support because of the
reference counting implementation inside of COW strings, which uses
atomics.  One would need something custom for that nonetheless.

Thus, the patch adds txnal clones as required.  They are new exported
symbols, but not visible to nontransactional code.  The only changes to
headers is transaction_safe[_dynamic] annotations where required by the
TS, and a few friend declarations.  The annotations are only enabled if
a user compiles with -fgnu-tm.  IOW, the changes are pretty much
invisible when not using the TM TS.

There are also commented-out calls to _ITM_setAssociatedException in the
code, which exist to show how we plan to support transaction
cancellation through exceptions (which needs some more libitm support
and bugfixes on the compiler side).

Tested on x86_64-linux and x86-linux.

OK?

2016-01-07  Torvald Riegel  <triegel@redhat.com>

	* include/bits/basic_string.h (basic_string): Declare friends.
	* include/bits/c++config (_GLIBCXX_TXN_SAFE,
	_GLIBCXX_TXN_SAFE_DYN, _GLIBCXX_USE_ALLOCATOR_NEW): New.
	* include/std/stdexcept (logic_error, domain_error, invalid_argument,
	length_error, out_of_range, runtime_error, range_error,
	underflow_error, overflow_error): Declare members as transaction-safe.
	(logic_error, runtime_error): Declare friend functions.
	* libsupc++/exception (exception, bad_exception): Declare members as
	transaction-safe.
	* src/c++11/cow-stdexcept.cc: Define transactional clones for the
	transaction-safe members of exceptions and helper functions.
	* libsupc++/eh_exception.cc: Adjust and define transactional clones.
	* config/abi/pre/gnu.ver (GLIBCXX_3.4.22) Add transactional clones.
	(CXXABI_1.3.10): New.
	* acinclude.m4 (GLIBCXX_CHECK_SIZE_T_MANGLING): New.
	(GLIBCXX_ENABLE_ALLOCATOR): Set ENABLE_ALLOCATOR_NEW.
	* configure.ac: Call GLIBCXX_CHECK_SIZE_T_MANGLING.
	* include/Makefile.am: Write ENABLE_ALLOCATOR_NEW to c++config.h.
	* include/Makefile.in: Regenerate.
	* config.h.in: Regenerate.
	* configure: Regenerate.

Comments

Jonathan Wakely Jan. 14, 2016, 5:58 p.m. UTC | #1
On 07/01/16 17:47 +0100, Torvald Riegel wrote:
>The attached patch makes some exceptions transaction-safe, as require by
>the Transactional Memory TS.  I believe I addressed all feedback for the
>previous version of this patch (in particular, there are now more safety
>checks for preconditions for this implementation (eg, that the new
>allocator is used), all exceptions declared by the TM TS are now
>supported (with the exception of tx_exception -- should I add that in a
>follow-up patch?)

Yes, that can be a separate patch, as it's adding a new type rather
than modifying the existing ones to add this TM magic.

>Thus, the patch adds txnal clones as required.  They are new exported
>symbols, but not visible to nontransactional code.  The only changes to
>headers is transaction_safe[_dynamic] annotations where required by the
>TS, and a few friend declarations.  The annotations are only enabled if
>a user compiles with -fgnu-tm.  IOW, the changes are pretty much
>invisible when not using the TM TS.

Thanks for adding all the clear comments as well. I'm sure we'll all
be grateful for those when we come to look back at the code.

>There are also commented-out calls to _ITM_setAssociatedException in the
>code, which exist to show how we plan to support transaction
>cancellation through exceptions (which needs some more libitm support
>and bugfixes on the compiler side).
>
>Tested on x86_64-linux and x86-linux.
>
>OK?

Yes, with some minor formatting changes noted below.

>@@ -129,12 +129,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>     logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
> #endif
> 
>-    virtual ~logic_error() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     /** Returns a C-style character string describing the general cause of
>      *  the current error (the same string passed to the ctor).  */
>     virtual const char* 
>-    what() const _GLIBCXX_USE_NOEXCEPT;
>+    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;

A blank line here please.

>+# ifdef _GLIBCXX_TM_TS_INTERNAL
>+    friend void*
>+    ::_txnal_logic_error_get_msg(void* e);
>+# endif
>   };
> 
>   /** Thrown by the library, or by you, to report domain errors (domain in


>@@ -208,21 +212,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>     runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT;
> #endif
> 
>-    virtual ~runtime_error() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     /** Returns a C-style character string describing the general cause of
>      *  the current error (the same string passed to the ctor).  */
>     virtual const char* 
>-    what() const _GLIBCXX_USE_NOEXCEPT;
>+    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;

And here.

>+# ifdef _GLIBCXX_TM_TS_INTERNAL
>+    friend void*
>+    ::_txnal_runtime_error_get_msg(void* e);
>+# endif
>   };
> 
>   /** Thrown to indicate range errors in internal computations.  */
>   class range_error : public runtime_error 
>   {
>   public:
>-    explicit range_error(const string& __arg);
>+    explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE;
> #if __cplusplus >= 201103L
>-    explicit range_error(const char*);
>+    explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
> #endif
>     virtual ~range_error() _GLIBCXX_USE_NOEXCEPT;
>   };


>diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception
>index 01dd9c2..8b8935d 100644
>--- a/libstdc++-v3/libsupc++/exception
>+++ b/libstdc++-v3/libsupc++/exception
>@@ -61,11 +61,12 @@ namespace std
>   {
>   public:
>     exception() _GLIBCXX_USE_NOEXCEPT { }
>-    virtual ~exception() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     /** Returns a C-style character string describing the general cause
>      *  of the current error.  */
>-    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
>+    virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN
>+	_GLIBCXX_USE_NOEXCEPT;
>   };

Please break this line after the return type, i.e.

    virtual const char*
    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;

>   /** If an %exception is thrown which is not listed in a function's
>@@ -77,10 +78,11 @@ namespace std
> 
>     // This declaration is not useless:
>     // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
>-    virtual ~bad_exception() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     // See comment in eh_exception.cc.
>-    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
>+    virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN
>+	_GLIBCXX_USE_NOEXCEPT;

Same here.
H.J. Lu Jan. 16, 2016, 10:58 p.m. UTC | #2
On Thu, Jan 7, 2016 at 8:47 AM, Torvald Riegel <triegel@redhat.com> wrote:
> The attached patch makes some exceptions transaction-safe, as require by
> the Transactional Memory TS.  I believe I addressed all feedback for the
> previous version of this patch (in particular, there are now more safety
> checks for preconditions for this implementation (eg, that the new
> allocator is used), all exceptions declared by the TM TS are now
> supported (with the exception of tx_exception -- should I add that in a
> follow-up patch?), and there is a test for the new functionality (as
> part of libitm's testsuite)).
>
> There are two things that complicate such support.  First, it seems
> better to not rely on -fgnu-tm of libstdc++ code for now (or at least we
> tried to avoid this so far).  Therefore, the transactional clones in
> this patch are all manually instrumented (ie, the functions are C
> functions with names matching the mangled names of the respective C++
> functions, and the _ZGTt prefix signaling that they are txnal clones).
>
> Second, exceptions still use a COW string internally, which cannot be
> made transaction-safe with just compiler support because of the
> reference counting implementation inside of COW strings, which uses
> atomics.  One would need something custom for that nonetheless.
>
> Thus, the patch adds txnal clones as required.  They are new exported
> symbols, but not visible to nontransactional code.  The only changes to
> headers is transaction_safe[_dynamic] annotations where required by the
> TS, and a few friend declarations.  The annotations are only enabled if
> a user compiles with -fgnu-tm.  IOW, the changes are pretty much
> invisible when not using the TM TS.
>
> There are also commented-out calls to _ITM_setAssociatedException in the
> code, which exist to show how we plan to support transaction
> cancellation through exceptions (which needs some more libitm support
> and bugfixes on the compiler side).
>
> Tested on x86_64-linux and x86-linux.
>
> OK?
>
> 2016-01-07  Torvald Riegel  <triegel@redhat.com>
>
>         * include/bits/basic_string.h (basic_string): Declare friends.
>         * include/bits/c++config (_GLIBCXX_TXN_SAFE,
>         _GLIBCXX_TXN_SAFE_DYN, _GLIBCXX_USE_ALLOCATOR_NEW): New.
>         * include/std/stdexcept (logic_error, domain_error, invalid_argument,
>         length_error, out_of_range, runtime_error, range_error,
>         underflow_error, overflow_error): Declare members as transaction-safe.
>         (logic_error, runtime_error): Declare friend functions.
>         * libsupc++/exception (exception, bad_exception): Declare members as
>         transaction-safe.
>         * src/c++11/cow-stdexcept.cc: Define transactional clones for the
>         transaction-safe members of exceptions and helper functions.
>         * libsupc++/eh_exception.cc: Adjust and define transactional clones.
>         * config/abi/pre/gnu.ver (GLIBCXX_3.4.22) Add transactional clones.
>         (CXXABI_1.3.10): New.
>         * acinclude.m4 (GLIBCXX_CHECK_SIZE_T_MANGLING): New.
>         (GLIBCXX_ENABLE_ALLOCATOR): Set ENABLE_ALLOCATOR_NEW.
>         * configure.ac: Call GLIBCXX_CHECK_SIZE_T_MANGLING.
>         * include/Makefile.am: Write ENABLE_ALLOCATOR_NEW to c++config.h.
>         * include/Makefile.in: Regenerate.
>         * config.h.in: Regenerate.
>         * configure: Regenerate.
>

Don't you need to update baseline_symbols.txt?
Jonathan Wakely Jan. 17, 2016, 4:59 p.m. UTC | #3
On 16 January 2016 at 22:58, H.J. Lu wrote:
> Don't you need to update baseline_symbols.txt?

That usually happens when we get near the release, not every time we
add symbols.
diff mbox

Patch

commit d4eda24eca5bf5d8d94f1d56762a9efd50294750
Author: Torvald Riegel <triegel@redhat.com>
Date:   Fri Nov 13 01:00:52 2015 +0100

    libstdc++: Make certain exceptions transaction_safe.

diff --git a/libitm/testsuite/libitm.c++/libstdc++-safeexc.C b/libitm/testsuite/libitm.c++/libstdc++-safeexc.C
new file mode 100644
index 0000000..3e1655e
--- /dev/null
+++ b/libitm/testsuite/libitm.c++/libstdc++-safeexc.C
@@ -0,0 +1,89 @@ 
+// Tests that the exceptions declared by the TM TS (N4514) as transaction_safe
+// are indeed that.  Thus, this also tests the transactional clones in
+// libstdc++ and libsupc++.
+
+// { dg-do run }
+
+#include <iostream>
+#include <exception>
+#include <stdexcept>
+#include <string>
+
+using namespace std;
+
+template<typename T> void thrower(const T& t)
+{
+  try
+    {
+      atomic_commit
+      {
+	throw t;
+      }
+    }
+  catch (T ex)
+    {
+      if (ex != t) abort ();
+    }
+}
+
+template<typename T> void thrower1(const string& what)
+{
+  try
+    {
+      atomic_commit
+      {
+	throw T ();
+      }
+    }
+  catch (T ex)
+    {
+      if (what != ex.what()) abort ();
+    }
+}
+
+template<typename T> void thrower2(const string& what)
+{
+  try
+    {
+      atomic_commit
+      {
+	throw T (what);
+      }
+    }
+  catch (T ex)
+    {
+      if (what != ex.what()) abort ();
+    }
+}
+
+
+int main ()
+{
+  thrower<unsigned int> (23);
+  thrower<int> (23);
+  thrower<unsigned short> (23);
+  thrower<short> (23);
+  thrower<unsigned char> (23);
+  thrower<char> (23);
+  thrower<unsigned long int> (42);
+  thrower<long int> (42);
+  thrower<unsigned long long int> (42);
+  thrower<long long int> (42);
+  thrower<double> (23.42);
+  thrower<long double> (23.42);
+  thrower<float> (23.42);
+  thrower<void*> (0);
+  thrower<void**> (0);
+  thrower1<exception> ("std::exception");
+  thrower1<bad_exception> ("std::bad_exception");
+  thrower2<logic_error> ("test");
+  thrower2<domain_error> ("test");
+  thrower2<invalid_argument> ("test");
+  thrower2<length_error> ("test");
+  thrower2<out_of_range> ("test");
+  thrower2<runtime_error> ("test");
+  thrower2<range_error> ("test");
+  thrower2<overflow_error> ("test");
+  thrower2<underflow_error> ("test");
+  return 0;
+}
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 75e4667..f3d12fc 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2560,6 +2560,8 @@  AC_DEFUN([GLIBCXX_ENABLE_ALLOCATOR], [
       ;;
   esac
 
+  GLIBCXX_CONDITIONAL(ENABLE_ALLOCATOR_NEW,
+		      test $enable_libstdcxx_allocator_flag = new)
   AC_SUBST(ALLOCATOR_H)
   AC_SUBST(ALLOCATOR_NAME)
 ])
@@ -4310,6 +4312,34 @@  dnl
   AC_LANG_RESTORE
 ])
 
+dnl
+dnl Check how size_t is mangled.  Copied from libitm.
+dnl
+AC_DEFUN([GLIBCXX_CHECK_SIZE_T_MANGLING], [
+  AC_CACHE_CHECK([how size_t is mangled],
+                 glibcxx_cv_size_t_mangling, [
+    AC_TRY_COMPILE([], [extern __SIZE_TYPE__ x; extern unsigned long x;],
+                   [glibcxx_cv_size_t_mangling=m], [
+      AC_TRY_COMPILE([], [extern __SIZE_TYPE__ x; extern unsigned int x;],
+                     [glibcxx_cv_size_t_mangling=j], [
+        AC_TRY_COMPILE([],
+                       [extern __SIZE_TYPE__ x; extern unsigned long long x;],
+                       [glibcxx_cv_size_t_mangling=y], [
+          AC_TRY_COMPILE([],
+                         [extern __SIZE_TYPE__ x; extern unsigned short x;],
+                         [glibcxx_cv_size_t_mangling=t],
+                         [glibcxx_cv_size_t_mangling=x])
+        ])
+      ])
+    ])
+  ])
+  if test $glibcxx_cv_size_t_mangling = x; then
+    AC_MSG_ERROR([Unknown underlying type for size_t])
+  fi
+  AC_DEFINE_UNQUOTED(_GLIBCXX_MANGLE_SIZE_T, [$glibcxx_cv_size_t_mangling],
+    [Define to the letter to which size_t is mangled.])
+])
+
 # Macros from the top-level gcc directory.
 m4_include([../config/gc++filt.m4])
 m4_include([../config/tls.m4])
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index b6cb7aa..47c85fc 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -788,6 +788,9 @@ 
 /* Define if compatibility should be provided for -mlong-double-64. */
 #undef _GLIBCXX_LONG_DOUBLE_COMPAT
 
+/* Define to the letter to which size_t is mangled. */
+#undef _GLIBCXX_MANGLE_SIZE_T
+
 /* Define if ptrdiff_t is int. */
 #undef _GLIBCXX_PTRDIFF_T_IS_INT
 
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index b324031..41069d1 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1876,6 +1876,37 @@  GLIBCXX_3.4.22 {
     _ZNSt6thread6_StateD[012]Ev;
     _ZNSt6thread15_M_start_threadESt10unique_ptrINS_6_StateESt14default_deleteIS1_EEPFvvE;
 
+    # Support for the Transactional Memory TS (N4514)
+    _ZGTtNSt11logic_errorC[12]EPKc;
+    _ZGTtNSt11logic_errorC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNKSt11logic_error4whatEv;
+    _ZGTtNSt11logic_errorD[012]Ev;
+    _ZGTtNSt12domain_errorC[12]EPKc;
+    _ZGTtNSt12domain_errorC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNSt12domain_errorD[012]Ev;
+    _ZGTtNSt16invalid_argumentC[12]EPKc;
+    _ZGTtNSt16invalid_argumentC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNSt16invalid_argumentD[012]Ev;
+    _ZGTtNSt12length_errorC[12]EPKc;
+    _ZGTtNSt12length_errorC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNSt12length_errorD[012]Ev;
+    _ZGTtNSt12out_of_rangeC[12]EPKc;
+    _ZGTtNSt12out_of_rangeC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNSt12out_of_rangeD[012]Ev;
+    _ZGTtNSt13runtime_errorC[12]EPKc;
+    _ZGTtNSt13runtime_errorC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNKSt13runtime_error4whatEv;
+    _ZGTtNSt13runtime_errorD[012]Ev;
+    _ZGTtNSt11range_errorC[12]EPKc;
+    _ZGTtNSt11range_errorC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNSt11range_errorD[012]Ev;
+    _ZGTtNSt14overflow_errorC[12]EPKc;
+    _ZGTtNSt14overflow_errorC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNSt14overflow_errorD[012]Ev;
+    _ZGTtNSt15underflow_errorC[12]EPKc;
+    _ZGTtNSt15underflow_errorC[12]ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE;
+    _ZGTtNSt15underflow_errorD[012]Ev;
+
 } GLIBCXX_3.4.21;
 
 # Symbols in the support library (libsupc++) have their own tag.
@@ -2109,6 +2140,16 @@  CXXABI_1.3.9 {
 
 } CXXABI_1.3.8;
 
+CXXABI_1.3.10 {
+
+    # Support for the Transactional Memory TS (N4514)
+    _ZGTtNKSt9exceptionD1Ev;
+    _ZGTtNKSt9exception4whatEv;
+    _ZGTtNKSt13bad_exceptionD1Ev;
+    _ZGTtNKSt13bad_exception4whatEv;
+
+} CXXABI_1.3.9;
+
 # Symbols in the support library (libsupc++) supporting transactional memory.
 CXXABI_TM_1 {
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 94120ec..85c0fc5 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -700,6 +700,8 @@  GLIBCXX_C_HEADERS_C_TRUE
 C_INCLUDE_DIR
 ALLOCATOR_NAME
 ALLOCATOR_H
+ENABLE_ALLOCATOR_NEW_FALSE
+ENABLE_ALLOCATOR_NEW_TRUE
 CLOCALE_INTERNAL_H
 CLOCALE_CC
 CTIME_CC
@@ -11594,7 +11596,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11597 "configure"
+#line 11599 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11700,7 +11702,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11703 "configure"
+#line 11705 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15386,7 +15388,7 @@  $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
   # Fake what AC_TRY_COMPILE does.
 
     cat > conftest.$ac_ext << EOF
-#line 15389 "configure"
+#line 15391 "configure"
 int main()
 {
   typedef bool atomic_type;
@@ -15421,7 +15423,7 @@  $as_echo "$glibcxx_cv_atomic_bool" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15424 "configure"
+#line 15426 "configure"
 int main()
 {
   typedef short atomic_type;
@@ -15456,7 +15458,7 @@  $as_echo "$glibcxx_cv_atomic_short" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15459 "configure"
+#line 15461 "configure"
 int main()
 {
   // NB: _Atomic_word not necessarily int.
@@ -15492,7 +15494,7 @@  $as_echo "$glibcxx_cv_atomic_int" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15495 "configure"
+#line 15497 "configure"
 int main()
 {
   typedef long long atomic_type;
@@ -15571,7 +15573,7 @@  $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15574 "configure"
+#line 15576 "configure"
 int main()
 {
   _Decimal32 d1;
@@ -15613,7 +15615,7 @@  ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15616 "configure"
+#line 15618 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -15647,7 +15649,7 @@  $as_echo "$enable_int128" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15650 "configure"
+#line 15652 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -16285,6 +16287,7 @@  $as_echo "$enable_libstdcxx_allocator_flag" >&6; }
 
 
 
+
    # Check whether --enable-cheaders was given.
 if test "${enable_cheaders+set}" = set; then :
   enableval=$enable_cheaders;
@@ -80246,6 +80249,99 @@  ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+# For Transactional Memory TS
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how size_t is mangled" >&5
+$as_echo_n "checking how size_t is mangled... " >&6; }
+if test "${glibcxx_cv_size_t_mangling+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+extern __SIZE_TYPE__ x; extern unsigned long x;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  glibcxx_cv_size_t_mangling=m
+else
+
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+extern __SIZE_TYPE__ x; extern unsigned int x;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  glibcxx_cv_size_t_mangling=j
+else
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+extern __SIZE_TYPE__ x; extern unsigned long long x;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  glibcxx_cv_size_t_mangling=y
+else
+
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+extern __SIZE_TYPE__ x; extern unsigned short x;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  glibcxx_cv_size_t_mangling=t
+else
+  glibcxx_cv_size_t_mangling=x
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_size_t_mangling" >&5
+$as_echo "$glibcxx_cv_size_t_mangling" >&6; }
+  if test $glibcxx_cv_size_t_mangling = x; then
+    as_fn_error "Unknown underlying type for size_t" "$LINENO" 5
+  fi
+
+cat >>confdefs.h <<_ACEOF
+#define _GLIBCXX_MANGLE_SIZE_T $glibcxx_cv_size_t_mangling
+_ACEOF
+
+
+
 # Define documentation rules conditionally.
 
 # See if makeinfo has been installed and is modern enough
@@ -80707,6 +80803,15 @@  else
 fi
 
 
+    if test $enable_libstdcxx_allocator_flag = new; then
+  ENABLE_ALLOCATOR_NEW_TRUE=
+  ENABLE_ALLOCATOR_NEW_FALSE='#'
+else
+  ENABLE_ALLOCATOR_NEW_TRUE='#'
+  ENABLE_ALLOCATOR_NEW_FALSE=
+fi
+
+
     if test $enable_cheaders = c; then
   GLIBCXX_C_HEADERS_C_TRUE=
   GLIBCXX_C_HEADERS_C_FALSE='#'
@@ -81226,6 +81331,10 @@  if test -z "${GLIBCXX_BUILD_PCH_TRUE}" && test -z "${GLIBCXX_BUILD_PCH_FALSE}";
   as_fn_error "conditional \"GLIBCXX_BUILD_PCH\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${ENABLE_ALLOCATOR_NEW_TRUE}" && test -z "${ENABLE_ALLOCATOR_NEW_FALSE}"; then
+  as_fn_error "conditional \"ENABLE_ALLOCATOR_NEW\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${GLIBCXX_C_HEADERS_C_TRUE}" && test -z "${GLIBCXX_C_HEADERS_C_FALSE}"; then
   as_fn_error "conditional \"GLIBCXX_C_HEADERS_C\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 4361cf0..9e19e99 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -408,6 +408,9 @@  AC_CHECK_HEADERS([fcntl.h dirent.h sys/statvfs.h utime.h])
 GLIBCXX_ENABLE_FILESYSTEM_TS
 GLIBCXX_CHECK_FILESYSTEM_DEPS
 
+# For Transactional Memory TS
+GLIBCXX_CHECK_SIZE_T_MANGLING
+
 # Define documentation rules conditionally.
 
 # See if makeinfo has been installed and is modern enough
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index b0a9373..ba8614c 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1199,6 +1199,14 @@  stamp-cxx11-abi:
 	echo 0 > stamp-cxx11-abi
 endif
 
+if ENABLE_ALLOCATOR_NEW
+stamp-allocator-new:
+	echo 1 > stamp-allocator-new
+else
+stamp-allocator-new:
+	echo 0 > stamp-allocator-new
+endif
+
 # NB: The non-empty default ldbl_compat works around an AIX sed
 # oddity, see libstdc++/31957 for details.
 ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
@@ -1209,13 +1217,15 @@  ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 			      stamp-visibility \
 			      stamp-extern-template \
 			      stamp-dual-abi \
-			      stamp-cxx11-abi
+			      stamp-cxx11-abi \
+			      stamp-allocator-new
 	@date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\
 	ns_version=`cat stamp-namespace-version` ;\
 	visibility=`cat stamp-visibility` ;\
 	externtemplate=`cat stamp-extern-template` ;\
 	dualabi=`cat stamp-dual-abi` ;\
 	cxx11abi=`cat stamp-cxx11-abi` ;\
+	allocatornew=`cat stamp-allocator-new` ;\
 	ldbl_compat='s,g,g,' ;\
 	grep "^[	 ]*#[	 ]*define[	 ][	 ]*_GLIBCXX_LONG_DOUBLE_COMPAT[	 ][	 ]*1[	 ]*$$" \
 	${CONFIG_HEADER} > /dev/null 2>&1 \
@@ -1226,6 +1236,7 @@  ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	-e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \
 	-e "s,define _GLIBCXX_USE_DUAL_ABI, define _GLIBCXX_USE_DUAL_ABI $$dualabi," \
 	-e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \
+	-e "s,define _GLIBCXX_USE_ALLOCATOR_NEW, define _GLIBCXX_USE_ALLOCATOR_NEW $$allocatornew," \
 	-e "$$ldbl_compat" \
 	    < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\
 	sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 5165154..66b4370 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -1630,6 +1630,11 @@  stamp-host: ${host_headers} ${bits_host_headers} ${ext_host_headers} ${host_head
 @ENABLE_CXX11_ABI_FALSE@stamp-cxx11-abi:
 @ENABLE_CXX11_ABI_FALSE@	echo 0 > stamp-cxx11-abi
 
+@ENABLE_ALLOCATOR_NEW_TRUE@stamp-allocator-new:
+@ENABLE_ALLOCATOR_NEW_TRUE@	echo 1 > stamp-allocator-new
+@ENABLE_ALLOCATOR_NEW_FALSE@stamp-allocator-new:
+@ENABLE_ALLOCATOR_NEW_FALSE@	echo 0 > stamp-allocator-new
+
 # NB: The non-empty default ldbl_compat works around an AIX sed
 # oddity, see libstdc++/31957 for details.
 ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
@@ -1640,13 +1645,15 @@  ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 			      stamp-visibility \
 			      stamp-extern-template \
 			      stamp-dual-abi \
-			      stamp-cxx11-abi
+			      stamp-cxx11-abi \
+			      stamp-allocator-new
 	@date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\
 	ns_version=`cat stamp-namespace-version` ;\
 	visibility=`cat stamp-visibility` ;\
 	externtemplate=`cat stamp-extern-template` ;\
 	dualabi=`cat stamp-dual-abi` ;\
 	cxx11abi=`cat stamp-cxx11-abi` ;\
+	allocatornew=`cat stamp-allocator-new` ;\
 	ldbl_compat='s,g,g,' ;\
 	grep "^[	 ]*#[	 ]*define[	 ][	 ]*_GLIBCXX_LONG_DOUBLE_COMPAT[	 ][	 ]*1[	 ]*$$" \
 	${CONFIG_HEADER} > /dev/null 2>&1 \
@@ -1657,6 +1664,7 @@  ${host_builddir}/c++config.h: ${CONFIG_HEADER} \
 	-e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \
 	-e "s,define _GLIBCXX_USE_DUAL_ABI, define _GLIBCXX_USE_DUAL_ABI $$dualabi," \
 	-e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \
+	-e "s,define _GLIBCXX_USE_ALLOCATOR_NEW, define _GLIBCXX_USE_ALLOCATOR_NEW $$allocatornew," \
 	-e "$$ldbl_compat" \
 	    < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\
 	sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index b9fcec3..17399a4 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -4904,6 +4904,18 @@  _GLIBCXX_END_NAMESPACE_CXX11
       int
       compare(size_type __pos, size_type __n1, const _CharT* __s,
 	      size_type __n2) const;
+
+# ifdef _GLIBCXX_TM_TS_INTERNAL
+      friend void
+      ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s,
+					    void* exc);
+      friend const char*
+      ::_txnal_cow_string_c_str(const void *that);
+      friend void
+      ::_txnal_cow_string_D1(void *that);
+      friend void
+      ::_txnal_cow_string_D1_commit(void *that);
+# endif
   };
 #endif  // !_GLIBCXX_USE_CXX11_ABI
 
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 6b13f5c..387a7bb 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -481,6 +481,22 @@  namespace std
 # define _GLIBCXX_BEGIN_EXTERN_C extern "C" {
 # define _GLIBCXX_END_EXTERN_C }
 
+#define _GLIBCXX_USE_ALLOCATOR_NEW
+
+// Conditionally enable annotations for the Transactional Memory TS on C++11.
+// Most of the following conditions are due to limitations in the current
+// implementation.
+#if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI			\
+  && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201505L	\
+  &&  !_GLIBCXX_FULLY_DYNAMIC_STRING && __GXX_WEAK__ 			\
+  && _GLIBCXX_USE_ALLOCATOR_NEW
+#define _GLIBCXX_TXN_SAFE transaction_safe
+#define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic
+#else
+#define _GLIBCXX_TXN_SAFE
+#define _GLIBCXX_TXN_SAFE_DYN
+#endif
+
 #else // !__cplusplus
 # define _GLIBCXX_BEGIN_EXTERN_C
 # define _GLIBCXX_END_EXTERN_C
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 9983501..2584429 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -117,11 +117,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   public:
     /** Takes a character string describing the error.  */
     explicit 
-    logic_error(const string& __arg);
+    logic_error(const string& __arg) _GLIBCXX_TXN_SAFE;
 
 #if __cplusplus >= 201103L
     explicit
-    logic_error(const char*);
+    logic_error(const char*) _GLIBCXX_TXN_SAFE;
 #endif
 
 #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
@@ -129,12 +129,16 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
 #endif
 
-    virtual ~logic_error() _GLIBCXX_USE_NOEXCEPT;
+    virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
 
     /** Returns a C-style character string describing the general cause of
      *  the current error (the same string passed to the ctor).  */
     virtual const char* 
-    what() const _GLIBCXX_USE_NOEXCEPT;
+    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+# ifdef _GLIBCXX_TM_TS_INTERNAL
+    friend void*
+    ::_txnal_logic_error_get_msg(void* e);
+# endif
   };
 
   /** Thrown by the library, or by you, to report domain errors (domain in
@@ -142,9 +146,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class domain_error : public logic_error 
   {
   public:
-    explicit domain_error(const string& __arg);
+    explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE;
 #if __cplusplus >= 201103L
-    explicit domain_error(const char*);
+    explicit domain_error(const char*) _GLIBCXX_TXN_SAFE;
 #endif
     virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT;
   };
@@ -153,9 +157,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class invalid_argument : public logic_error 
   {
   public:
-    explicit invalid_argument(const string& __arg);
+    explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE;
 #if __cplusplus >= 201103L
-    explicit invalid_argument(const char*);
+    explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE;
 #endif
     virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT;
   };
@@ -165,9 +169,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class length_error : public logic_error 
   {
   public:
-    explicit length_error(const string& __arg);
+    explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE;
 #if __cplusplus >= 201103L
-    explicit length_error(const char*);
+    explicit length_error(const char*) _GLIBCXX_TXN_SAFE;
 #endif
     virtual ~length_error() _GLIBCXX_USE_NOEXCEPT;
   };
@@ -177,9 +181,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class out_of_range : public logic_error 
   {
   public:
-    explicit out_of_range(const string& __arg);
+    explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE;
 #if __cplusplus >= 201103L
-    explicit out_of_range(const char*);
+    explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE;
 #endif
     virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT;
   };
@@ -196,11 +200,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   public:
     /** Takes a character string describing the error.  */
     explicit 
-    runtime_error(const string& __arg);
+    runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE;
 
 #if __cplusplus >= 201103L
     explicit
-    runtime_error(const char*);
+    runtime_error(const char*) _GLIBCXX_TXN_SAFE;
 #endif
 
 #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
@@ -208,21 +212,25 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT;
 #endif
 
-    virtual ~runtime_error() _GLIBCXX_USE_NOEXCEPT;
+    virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
 
     /** Returns a C-style character string describing the general cause of
      *  the current error (the same string passed to the ctor).  */
     virtual const char* 
-    what() const _GLIBCXX_USE_NOEXCEPT;
+    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+# ifdef _GLIBCXX_TM_TS_INTERNAL
+    friend void*
+    ::_txnal_runtime_error_get_msg(void* e);
+# endif
   };
 
   /** Thrown to indicate range errors in internal computations.  */
   class range_error : public runtime_error 
   {
   public:
-    explicit range_error(const string& __arg);
+    explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE;
 #if __cplusplus >= 201103L
-    explicit range_error(const char*);
+    explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
 #endif
     virtual ~range_error() _GLIBCXX_USE_NOEXCEPT;
   };
@@ -231,9 +239,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class overflow_error : public runtime_error 
   {
   public:
-    explicit overflow_error(const string& __arg);
+    explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
 #if __cplusplus >= 201103L
-    explicit overflow_error(const char*);
+    explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE;
 #endif
     virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT;
   };
@@ -242,9 +250,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class underflow_error : public runtime_error 
   {
   public:
-    explicit underflow_error(const string& __arg);
+    explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE;
 #if __cplusplus >= 201103L
-    explicit underflow_error(const char*);
+    explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE;
 #endif
     virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT;
   };
diff --git a/libstdc++-v3/libsupc++/eh_exception.cc b/libstdc++-v3/libsupc++/eh_exception.cc
index cfd835a..32f9df7 100644
--- a/libstdc++-v3/libsupc++/eh_exception.cc
+++ b/libstdc++-v3/libsupc++/eh_exception.cc
@@ -26,16 +26,18 @@ 
 #include "exception"
 #include <cxxabi.h>
 
-std::exception::~exception() _GLIBCXX_USE_NOEXCEPT { }
+std::exception::~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT { }
 
-std::bad_exception::~bad_exception() _GLIBCXX_USE_NOEXCEPT { }
+std::bad_exception::~bad_exception() _GLIBCXX_TXN_SAFE_DYN
+    _GLIBCXX_USE_NOEXCEPT
+{ }
 
 abi::__forced_unwind::~__forced_unwind() throw() { }
 
 abi::__foreign_exception::~__foreign_exception() throw() { }
 
 const char* 
-std::exception::what() const _GLIBCXX_USE_NOEXCEPT
+std::exception::what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT
 {
   // NB: Another elegant option would be returning typeid(*this).name()
   // and not overriding what() in bad_exception, bad_alloc, etc.  In
@@ -44,7 +46,41 @@  std::exception::what() const _GLIBCXX_USE_NOEXCEPT
 }
 
 const char* 
-std::bad_exception::what() const _GLIBCXX_USE_NOEXCEPT
+std::bad_exception::what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT
 {
   return "std::bad_exception";
 }
+
+// Transactional clones for the destructors and what().
+// what() is effectively transaction_pure, but we do not want to annotate it
+// as such; thus, we call exactly the respective nontransactional function.
+extern "C" {
+
+void
+_ZGTtNKSt9exceptionD1Ev(const std::exception*)
+{ }
+
+const char*
+_ZGTtNKSt9exception4whatEv(const std::exception* that)
+{
+  // We really want the non-virtual call here.  We already executed the
+  // indirect call representing the virtual call, and the TM runtime or the
+  // compiler resolved it to this transactional clone.  In the clone, we want
+  // to do the same as for the nontransactional original, so we just call it.
+  return that->std::exception::what();
+}
+
+void
+_ZGTtNKSt13bad_exceptionD1Ev(
+    const std::bad_exception*)
+{ }
+
+const char*
+_ZGTtNKSt13bad_exception4whatEv(
+    const std::bad_exception* that)
+{
+  // Also see _ZGTtNKSt9exception4whatEv.
+  return that->std::bad_exception::what();
+}
+
+}
diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception
index 01dd9c2..8b8935d 100644
--- a/libstdc++-v3/libsupc++/exception
+++ b/libstdc++-v3/libsupc++/exception
@@ -61,11 +61,12 @@  namespace std
   {
   public:
     exception() _GLIBCXX_USE_NOEXCEPT { }
-    virtual ~exception() _GLIBCXX_USE_NOEXCEPT;
+    virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
 
     /** Returns a C-style character string describing the general cause
      *  of the current error.  */
-    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
+    virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN
+	_GLIBCXX_USE_NOEXCEPT;
   };
 
   /** If an %exception is thrown which is not listed in a function's
@@ -77,10 +78,11 @@  namespace std
 
     // This declaration is not useless:
     // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
-    virtual ~bad_exception() _GLIBCXX_USE_NOEXCEPT;
+    virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
 
     // See comment in eh_exception.cc.
-    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
+    virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN
+	_GLIBCXX_USE_NOEXCEPT;
   };
 
   /// If you write a replacement %terminate handler, it must be of this type.
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 782b96c..5c7b0ff 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -26,6 +26,21 @@ 
 // ISO C++ 14882: 19.1  Exception classes
 //
 
+// Enable hooks for support for the Transactional Memory TS (N4514).
+#define _GLIBCXX_TM_TS_INTERNAL
+void
+_txnal_cow_string_C1_for_exceptions(void* that, const char* s, void* exc);
+const char*
+_txnal_cow_string_c_str(const void* that);
+void
+_txnal_cow_string_D1(void* that);
+void
+_txnal_cow_string_D1_commit(void* that);
+void*
+_txnal_logic_error_get_msg(void* e);
+void*
+_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
@@ -151,3 +166,277 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+// Support for the Transactional Memory TS (N4514).
+//
+// logic_error and runtime_error both carry a message in the form of a COW
+// string.  This COW string is never made visible to users of the exception
+// because what() returns a C string.  The COW string can be constructed as
+// either a copy of a COW string of another logic_error/runtime_error, or
+// using a C string or SSO string; thus, the COW string's _Rep is only
+// accessed by logic_error operations.  We control all txnal clones of those
+// operations and thus can ensure that _Rep is never accessed transactionally.
+// Furthermore, _Rep will always have been allocated or deallocated via
+// global new or delete, so nontransactional writes we do to _Rep cannot
+// interfere with transactional accesses.
+extern "C" {
+
+#ifndef _GLIBCXX_MANGLE_SIZE_T
+#error Mangled name of size_t type not defined.
+#endif
+#define CONCAT1(x,y)		x##y
+#define CONCAT(x,y)		CONCAT1(x,y)
+#define _ZGTtnaX		CONCAT(_ZGTtna,_GLIBCXX_MANGLE_SIZE_T)
+
+#ifdef __i386__
+/* Only for 32-bit x86.  */
+# define ITM_REGPARM	__attribute__((regparm(2)))
+#else
+# define ITM_REGPARM
+#endif
+
+#if __GXX_WEAK__
+// Declare all libitm symbols we rely on, but make them weak so that we do
+// not depend on libitm.
+extern void* _ZGTtnaX (size_t sz) _GLIBCXX_WEAK_DEFINITION;
+extern void _ZGTtdlPv (void* ptr) _GLIBCXX_WEAK_DEFINITION;
+extern uint8_t _ITM_RU1(const uint8_t *p)
+  ITM_REGPARM _GLIBCXX_WEAK_DEFINITION;
+extern uint32_t _ITM_RU4(const uint32_t *p)
+  ITM_REGPARM _GLIBCXX_WEAK_DEFINITION;
+extern uint64_t _ITM_RU8(const uint64_t *p)
+  ITM_REGPARM _GLIBCXX_WEAK_DEFINITION;
+extern void _ITM_memcpyRtWn(void *, const void *, size_t)
+  ITM_REGPARM _GLIBCXX_WEAK_DEFINITION;
+extern void _ITM_memcpyRnWt(void *, const void *, size_t)
+  ITM_REGPARM _GLIBCXX_WEAK_DEFINITION;
+extern void _ITM_addUserCommitAction(void (*)(void *), uint64_t, void *)
+  ITM_REGPARM _GLIBCXX_WEAK_DEFINITION;
+
+#else
+// If there is no support for weak symbols, create dummies.  The exceptions
+// will not be declared transaction_safe in this case.
+void* _ZGTtnaX (size_t) { return NULL; }
+void _ZGTtdlPv (void*) { }
+uint8_t _ITM_RU1(const uint8_t *) { return 0; }
+uint32_t _ITM_RU4(const uint32_t *) { return 0; }
+uint64_t _ITM_RU8(const uint64_t *) { return 0; }
+void _ITM_memcpyRtWn(void *, const void *, size_t) { }
+void _ITM_memcpyRnWt(void *, const void *, size_t) { }
+void _ITM_addUserCommitAction(void (*)(void *), uint64_t, void *) { };
+#endif
+
+}
+
+// A transactional version of basic_string::basic_string(const char *s)
+// that also notifies the TM runtime about allocations belonging to this
+// exception.
+void
+_txnal_cow_string_C1_for_exceptions(void* that, const char* s, void *exc)
+{
+  typedef std::basic_string<char> bs_type;
+  bs_type *bs = (bs_type*) that;
+
+  // First, do a transactional strlen, but including the trailing zero.
+  bs_type::size_type len = 1;
+  for (const char *ss = s; _ITM_RU1((const uint8_t*) ss) != 0; ss++, len++);
+
+
+  // Allocate memory for the string and the refcount.  We use the
+  // transactional clone of global new[]; if this throws, it will do so in a
+  // transaction-compatible way.
+  // The allocation belongs to this exception, so tell the runtime about it.
+  // TODO Once this is supported, link the following allocation to this
+  // exception: void *prev = _ITM_setAssociatedException(exc);
+  bs_type::_Rep *rep;
+  try
+    {
+      rep = (bs_type::_Rep*) _ZGTtnaX (len + sizeof (bs_type::_Rep));
+    }
+  catch (...)
+    {
+      // Pop the association with this exception.
+      // TODO Once this is supported, link the following allocation to this
+      // exception: _ITM_setAssociatedException(prev);
+      // We do not need to instrument a rethrow.
+      throw;
+    }
+  // Pop the association with this exception.
+  // TODO Once this is supported, link the following allocation to this
+  // exception: _ITM_setAssociatedException(prev);
+
+  // Now initialize the rest of the string and copy the C string.  The memory
+  // will be freshly allocated, so nontransactional accesses are sufficient,
+  // including the writes when copying the string (see above).
+  rep->_M_set_sharable();
+  rep->_M_length = rep->_M_capacity = len - 1;
+  _ITM_memcpyRtWn(rep->_M_refdata(), s, len);
+  new (&bs->_M_dataplus) bs_type::_Alloc_hider(rep->_M_refdata(),
+					       bs_type::allocator_type());
+}
+
+static void* txnal_read_ptr(void* const * ptr)
+{
+  static_assert(sizeof(uint64_t) == sizeof(void*)
+		|| sizeof(uint32_t) == sizeof(void*));
+  // FIXME make a true compile-time choice to prevent warnings.
+#if __UINTPTR_MAX__ == __UINT64_MAX__
+  return (void*)_ITM_RU8((const uint64_t*)ptr);
+#else
+  return (void*)_ITM_RU4((const uint32_t*)ptr);
+#endif
+}
+
+// We must access the data pointer in the COW string transactionally because
+// another transaction can delete the string and reuse the memory.
+const char*
+_txnal_cow_string_c_str(const void* that)
+{
+  typedef std::basic_string<char> bs_type;
+  const bs_type *bs = (const bs_type*) that;
+
+  return (const char*) txnal_read_ptr((void**)&bs->_M_dataplus._M_p);
+}
+
+const char*
+_txnal_sso_string_c_str(const void* that)
+{
+  return (const char*) txnal_read_ptr(
+      (void* const*)const_cast<char* const*>(
+	  &((const std::__sso_string*) that)->_M_s._M_p));
+}
+
+void
+_txnal_cow_string_D1_commit(void* data)
+{
+  typedef std::basic_string<char> bs_type;
+  bs_type::_Rep *rep = (bs_type::_Rep*) data;
+  rep->_M_dispose(bs_type::allocator_type());
+}
+
+void
+_txnal_cow_string_D1(void* that)
+{
+  typedef std::basic_string<char> bs_type;
+  bs_type::_Rep *rep = reinterpret_cast<bs_type::_Rep*>(
+      const_cast<char*>(_txnal_cow_string_c_str(that))) - 1;
+
+  // The string can be shared, in which case we would need to decrement the
+  // reference count.  We cannot undo that because we might lose the string
+  // otherwise.  Therefore, we register a commit action that will dispose of
+  // the string's _Rep.
+  enum {_ITM_noTransactionId  = 1};
+  _ITM_addUserCommitAction(_txnal_cow_string_D1_commit, _ITM_noTransactionId,
+			   rep);
+}
+
+void*
+_txnal_logic_error_get_msg(void* e)
+{
+  std::logic_error* le = (std::logic_error*) e;
+  return &le->_M_msg;
+}
+
+void*
+_txnal_runtime_error_get_msg(void* e)
+{
+  std::runtime_error* le = (std::runtime_error*) e;
+  return &le->_M_msg;
+}
+
+// The constructors are only declared transaction-safe if the C++11 ABI is
+// used for std::string and the exception classes use a COW string internally.
+// A user must not call these constructors otherwise; if they do, it will
+// result in undefined behavior, which is in this case not initializing this
+// string.
+#if _GLIBCXX_USE_DUAL_ABI
+#define CTORDTORSTRINGCSTR(s) _txnal_sso_string_c_str((s))
+#else
+#define CTORDTORSTRINGCSTR(s) ""
+#endif
+
+// This macro defines transaction constructors and destructors for a specific
+// exception class.  NAME is the variable part of the mangled name, CLASS is
+// the class name, and BASE must be logic_error or runtime_error (which is
+// then used to call the proper friend function that can return a pointer to
+// the _M_msg member declared by the given (base) class).
+#define CTORDTOR(NAME, CLASS, BASE)					\
+void									\
+_ZGTtNSt##NAME##C1EPKc (CLASS* that, const char* s)			\
+{									\
+  /* This will use the singleton _Rep for an empty string and just	\
+     point to it instead of allocating memory.  Thus, we can use it as	\
+     source, copy it into the object we are constructing, and then	\
+     construct the COW string in the latter manually.  Note that the	\
+     exception classes will not be declared transaction_safe if the	\
+     shared empty _Rep is disabled with --enable-fully-dynamic-string	\
+     (in which case _GLIBCXX_FULLY_DYNAMIC_STRING is nonzero).  */	\
+  CLASS e("");								\
+  _ITM_memcpyRnWt(that, &e, sizeof(CLASS));				\
+  _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that),	\
+				      s, that);				\
+}									\
+void									\
+_ZGTtNSt##NAME##C2EPKc (CLASS*, const char*)				\
+  __attribute__((alias ("_ZGTtNSt" #NAME "C1EPKc")));			\
+void									\
+_ZGTtNSt##NAME##C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
+    CLASS* that, const std::__sso_string& s)				\
+{									\
+  CLASS e("");								\
+  _ITM_memcpyRnWt(that, &e, sizeof(CLASS));				\
+  /* Get the C string from the SSO string.  */				\
+  _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that),	\
+				      CTORDTORSTRINGCSTR(&s), that);	\
+}									\
+void									\
+_ZGTtNSt##NAME##C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
+    CLASS*, const std::__sso_string&) __attribute__((alias		\
+("_ZGTtNSt" #NAME							\
+  "C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")));	\
+void									\
+_ZGTtNSt##NAME##D1Ev(CLASS* that)					\
+{ _txnal_cow_string_D1(_txnal_##BASE##_get_msg(that)); }		\
+void									\
+_ZGTtNSt##NAME##D2Ev(CLASS*)						\
+__attribute__((alias ("_ZGTtNSt" #NAME "D1Ev")));			\
+void									\
+_ZGTtNSt##NAME##D0Ev(CLASS* that)					\
+{									\
+  _ZGTtNSt##NAME##D1Ev(that);						\
+  _ZGTtdlPv(that);							\
+}
+
+// Now create all transactional constructors and destructors, as well as the
+// two virtual what() functions.
+extern "C" {
+
+CTORDTOR(11logic_error, std::logic_error, logic_error)
+
+const char*
+_ZGTtNKSt11logic_error4whatEv(const std::logic_error* that)
+{
+  return _txnal_cow_string_c_str(_txnal_logic_error_get_msg(
+      const_cast<std::logic_error*>(that)));
+}
+
+CTORDTOR(12domain_error, std::domain_error, logic_error)
+CTORDTOR(16invalid_argument, std::invalid_argument, logic_error)
+CTORDTOR(12length_error, std::length_error, logic_error)
+CTORDTOR(12out_of_range, std::out_of_range, logic_error)
+
+
+CTORDTOR(13runtime_error, std::runtime_error, runtime_error)
+
+const char*
+_ZGTtNKSt13runtime_error4whatEv(const std::runtime_error* that)
+{
+  return _txnal_cow_string_c_str(_txnal_runtime_error_get_msg(
+      const_cast<std::runtime_error*>(that)));
+}
+
+CTORDTOR(11range_error, std::range_error, runtime_error)
+CTORDTOR(14overflow_error, std::overflow_error, runtime_error)
+CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
+
+}