libstdc++: Make certain exceptions transaction_safe.
authorTorvald Riegel <triegel@redhat.com>
Fri, 15 Jan 2016 22:42:41 +0000 (22:42 +0000)
committerTorvald Riegel <torvald@gcc.gnu.org>
Fri, 15 Jan 2016 22:42:41 +0000 (22:42 +0000)
From-SVN: r232454

17 files changed:
libitm/ChangeLog
libitm/testsuite/libitm.c++/libstdc++-safeexc.C [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/acinclude.m4
libstdc++-v3/config.h.in
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/configure
libstdc++-v3/configure.ac
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/c++config
libstdc++-v3/include/std/stdexcept
libstdc++-v3/libsupc++/eh_exception.cc
libstdc++-v3/libsupc++/exception
libstdc++-v3/src/c++11/cow-stdexcept.cc
libstdc++-v3/testsuite/util/testsuite_abi.cc

index adcbf1d4f571d9c6c4fa9e634179ae546d3faa2f..5026833da76f9e8a810f3a3d5d414e3084255fc8 100644 (file)
@@ -1,3 +1,7 @@
+2015-01-15  Torvald Riegel  <triegel@redhat.com>
+
+       testsuite/libitm.c++/libstdc++-safeexc.C: New.
+
 2016-01-13  Torvald Riegel  <triegel@redhat.com>
 
        * beginend.cc (gtm_thread::trycommit): Fix seq_cst fences.
diff --git a/libitm/testsuite/libitm.c++/libstdc++-safeexc.C b/libitm/testsuite/libitm.c++/libstdc++-safeexc.C
new file mode 100644 (file)
index 0000000..3e1655e
--- /dev/null
@@ -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;
+}
index 0d8c24ca936ec30cb32bedfee8a73fad0f46c0ce..0c9728bd44bb09ae21e34d68e55ce9525afd2708 100644 (file)
@@ -1,3 +1,28 @@
+2016-01-15  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.
+       * testsuite/util/testsuite_abi.cc (check_version): Add CXXABI_1.3.10.
+
 2016-01-15  Steve Ellcey  <sellcey@imgtec.com>
 
        * include/ext/random.tcc: Use __builtin_isfinite instead of
index b76e8d51b960beffa4fba96b5715c0024fe87211..1e256603a2985c35db5904a54f76c211ff540fb0 100644 (file)
@@ -2594,6 +2594,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)
 ])
@@ -4344,6 +4346,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])
index 5fb0cd3dc26574c51414ecb00e726106d970646c..4600b2366db603680e3330a283f830d1bc7f0fd3 100644 (file)
 /* 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
 
index b32403155631a57cad061d56e719c813920efe3d..41069d156a3367ebdf5c4491589f0e22d0e1b390 100644 (file)
@@ -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 {
 
index 38f14f6729ebfd76816ebf34d301eecc65ea0035..94e88a52d7c76e3cf7f189e1027c918b88220343 100755 (executable)
@@ -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;
@@ -80294,6 +80297,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
@@ -80755,6 +80851,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='#'
@@ -81274,6 +81379,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
index 4361cf0e4508b1df56c8d3172710a7608a22d84c..9e19e9927fd1b56e24199189cc8e4df505855b73 100644 (file)
@@ -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
index 07dc48a556781682aac5b18088e9692c9e72bfa4..39327d98b27b015bdfd2c3dad5db80481d8ad728 100644 (file)
@@ -1200,6 +1200,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} \
@@ -1210,13 +1218,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 \
@@ -1227,6 +1237,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' \
index f2fb4daeb05ccc2bc339e44b47cb076b8ff3349f..e74fae8b849c49c72ccafd3eb2f0b79a892dad52 100644 (file)
@@ -1631,6 +1631,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} \
@@ -1641,13 +1646,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 \
@@ -1658,6 +1665,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' \
index e7460bbed213614821ce5b687637acc0789d24b9..374c9851539d379bdaf0c308a2c154cc987349e7 100644 (file)
@@ -4902,6 +4902,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
 
index 6b13f5c625136c7bcc5729682e470136a52dd264..387a7bb57fefe49425f4a018ce3459119f6285bd 100644 (file)
@@ -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
index 9983501150ad74455a30c25cec4a88efb66621d0..aef27cc361712fddf3d82441e7d7f9207927ef13 100644 (file)
@@ -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,17 @@ _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 +147,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 +158,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 +170,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 +182,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 +201,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 +213,26 @@ _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 +241,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 +252,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;
   };
index cfd835a845e22ad83beb7242110ea624dc64b785..32f9df73a66cd13395c2baa8b4e45942f0f90a7e 100644 (file)
 #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();
+}
+
+}
index 01dd9c296db3abcb5de0421556cea2b2eb39f5cc..63631f6d1d125fc5d599d317753001070318906d 100644 (file)
@@ -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.
index 782b96c6d4f80f1ef7d054660fbe16be893add1d..afc3f6cddf7c952fc1c0ce86252ed121c7d8a435 100644 (file)
 // 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) __attribute__((weak));
+extern void _ZGTtdlPv (void* ptr) __attribute__((weak));
+extern uint8_t _ITM_RU1(const uint8_t *p)
+  ITM_REGPARM __attribute__((weak));
+extern uint32_t _ITM_RU4(const uint32_t *p)
+  ITM_REGPARM __attribute__((weak));
+extern uint64_t _ITM_RU8(const uint64_t *p)
+  ITM_REGPARM __attribute__((weak));
+extern void _ITM_memcpyRtWn(void *, const void *, size_t)
+  ITM_REGPARM __attribute__((weak));
+extern void _ITM_memcpyRnWt(void *, const void *, size_t)
+  ITM_REGPARM __attribute__((weak));
+extern void _ITM_addUserCommitAction(void (*)(void *), uint64_t, void *)
+  ITM_REGPARM __attribute__((weak));
+
+#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)
+
+}
index bb7ef6d9ce029c5aebea7dd1fc234e20fb1b2fd7..caf154400f952e87686f68c8e3e44120137bb589 100644 (file)
@@ -214,6 +214,7 @@ check_version(symbol& test, bool added)
       known_versions.push_back("CXXABI_1.3.7");
       known_versions.push_back("CXXABI_1.3.8");
       known_versions.push_back("CXXABI_1.3.9");
+      known_versions.push_back("CXXABI_1.3.10");
       known_versions.push_back("CXXABI_TM_1");
       known_versions.push_back("CXXABI_FLOAT128");
     }
@@ -232,7 +233,7 @@ check_version(symbol& test, bool added)
 
       // Check that added symbols are added in the latest pre-release version.
       bool latestp = (test.version_name == "GLIBCXX_3.4.22"
-                    || test.version_name == "CXXABI_1.3.9"
+                    || test.version_name == "CXXABI_1.3.10"
                     || test.version_name == "CXXABI_FLOAT128"
                     || test.version_name == "CXXABI_TM_1");
       if (added && !latestp)