From a04d5fc95d7494824b07feb6c57cf71b4891e3de Mon Sep 17 00:00:00 2001 From: Torvald Riegel Date: Fri, 15 Jan 2016 22:42:41 +0000 Subject: [PATCH] libstdc++: Make certain exceptions transaction_safe. From-SVN: r232454 --- libitm/ChangeLog | 4 + .../testsuite/libitm.c++/libstdc++-safeexc.C | 89 ++++++ libstdc++-v3/ChangeLog | 25 ++ libstdc++-v3/acinclude.m4 | 30 ++ libstdc++-v3/config.h.in | 3 + libstdc++-v3/config/abi/pre/gnu.ver | 41 +++ libstdc++-v3/configure | 127 +++++++- libstdc++-v3/configure.ac | 3 + libstdc++-v3/include/Makefile.am | 13 +- libstdc++-v3/include/Makefile.in | 10 +- libstdc++-v3/include/bits/basic_string.h | 12 + libstdc++-v3/include/bits/c++config | 16 + libstdc++-v3/include/std/stdexcept | 54 ++-- libstdc++-v3/libsupc++/eh_exception.cc | 44 ++- libstdc++-v3/libsupc++/exception | 10 +- libstdc++-v3/src/c++11/cow-stdexcept.cc | 289 ++++++++++++++++++ libstdc++-v3/testsuite/util/testsuite_abi.cc | 3 +- 17 files changed, 731 insertions(+), 42 deletions(-) create mode 100644 libitm/testsuite/libitm.c++/libstdc++-safeexc.C diff --git a/libitm/ChangeLog b/libitm/ChangeLog index adcbf1d4f57..5026833da76 100644 --- a/libitm/ChangeLog +++ b/libitm/ChangeLog @@ -1,3 +1,7 @@ +2015-01-15 Torvald Riegel + + testsuite/libitm.c++/libstdc++-safeexc.C: New. + 2016-01-13 Torvald Riegel * 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 index 00000000000..3e1655e83ec --- /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 +#include +#include +#include + +using namespace std; + +template void thrower(const T& t) +{ + try + { + atomic_commit + { + throw t; + } + } + catch (T ex) + { + if (ex != t) abort (); + } +} + +template void thrower1(const string& what) +{ + try + { + atomic_commit + { + throw T (); + } + } + catch (T ex) + { + if (what != ex.what()) abort (); + } +} + +template void thrower2(const string& what) +{ + try + { + atomic_commit + { + throw T (what); + } + } + catch (T ex) + { + if (what != ex.what()) abort (); + } +} + + +int main () +{ + thrower (23); + thrower (23); + thrower (23); + thrower (23); + thrower (23); + thrower (23); + thrower (42); + thrower (42); + thrower (42); + thrower (42); + thrower (23.42); + thrower (23.42); + thrower (23.42); + thrower (0); + thrower (0); + thrower1 ("std::exception"); + thrower1 ("std::bad_exception"); + thrower2 ("test"); + thrower2 ("test"); + thrower2 ("test"); + thrower2 ("test"); + thrower2 ("test"); + thrower2 ("test"); + thrower2 ("test"); + thrower2 ("test"); + thrower2 ("test"); + return 0; +} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0d8c24ca936..0c9728bd44b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2016-01-15 Torvald Riegel + + * 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 * include/ext/random.tcc: Use __builtin_isfinite instead of diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index b76e8d51b96..1e256603a29 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -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]) diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index 5fb0cd3dc26..4600b2366db 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -791,6 +791,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 b3240315563..41069d156a3 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 38f14f6729e..94e88a52d7c 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 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 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 diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 4361cf0e450..9e19e9927fd 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 07dc48a5567..39327d98b27 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -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' \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index f2fb4daeb05..e74fae8b849 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -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' \ diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index e7460bbed21..374c9851539 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -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 diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 6b13f5c6251..387a7bb57fe 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 9983501150a..aef27cc3617 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,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; }; diff --git a/libstdc++-v3/libsupc++/eh_exception.cc b/libstdc++-v3/libsupc++/eh_exception.cc index cfd835a845e..32f9df73a66 100644 --- a/libstdc++-v3/libsupc++/eh_exception.cc +++ b/libstdc++-v3/libsupc++/eh_exception.cc @@ -26,16 +26,18 @@ #include "exception" #include -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 01dd9c296db..63631f6d1d1 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 782b96c6d4f..afc3f6cddf7 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) __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 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 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( + &((const std::__sso_string*) that)->_M_s._M_p)); +} + +void +_txnal_cow_string_D1_commit(void* data) +{ + typedef std::basic_string 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 bs_type; + bs_type::_Rep *rep = reinterpret_cast( + const_cast(_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(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(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) + +} diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index bb7ef6d9ce0..caf154400f9 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -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)