libstdc++: Make certain exceptions transaction_safe.
From-SVN: r232454
This commit is contained in:
parent
40c43acacc
commit
a04d5fc95d
@ -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.
|
||||
|
89
libitm/testsuite/libitm.c++/libstdc++-safeexc.C
Normal file
89
libitm/testsuite/libitm.c++/libstdc++-safeexc.C
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
127
libstdc++-v3/configure
vendored
127
libstdc++-v3/configure
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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' \
|
||||
|
@ -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' \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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<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)
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user