diff options
Diffstat (limited to 'libstdc++-v3')
43 files changed, 780 insertions, 173 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0fa50390352..d0f773dfb58 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,139 @@ +2005-11-23 Paolo Carlini <pcarlini@suse.de> + + PR libstdc++/24975 (basic_string) + * include/bits/basic_string.h (_Rep::_S_empty_rep): Avoid + strict-aliasing warnings. + +2005-11-22 Paolo Carlini <pcarlini@suse.de> + + PR libstdc++/24975 + * include/bits/stl_set.h (insert(iterator, const value_type&), + erase(iterator), erase(iterator, iterator)): Don't break aliasing + rules casting to _Rep_iterator&, forward to _Rb_tree facilities. + * include/bits/stl_multiset.h (insert(iterator, const value_type&), + erase(iterator), erase(iterator, iterator)): Likewise. + * include/bits/stl_tree.h (_Rb_tree<>::_M_insert(_Const_Base_ptr, + _Const_Base_ptr, const value_type&), insert_unique(const_iterator, + const value_type&), insert_equal(const_iterator, const value_type&), + erase(const_iterator), erase(const_iterator, const_iterator)): New, + _Rb_tree<>::const_iterator counterparts of existing facilities. + +2005-11-21 Benjamin Kosnik <bkoz@redhat.com> + Ulrich Drepper <drepper@redhat.com> + + PR libstdc++/23591 + * scripts/create_testsuite_files: Support for "C" test files. + * testsuite/lib/libstdc++.exp: Same. + * testsuite/libstdc++-dg/normal.exp: Same. + * testsuite/ext/mt_allocator/22309_thread.cc: Update names. + * testsuite/19_diagnostics/23591_thread-1.c: New. + * testsuite/testsuite_shared.cc: Add tests, rename existing functions. + * libsupc++/eh_globals.cc: Make global thread local if possible. + * configure.ac: Use GCC_CHECK_TLS. + * acinclude.m4: Include tls.m4. + * configure: Regenerate. + * config.h.in: Same. + +2005-11-21 Benjamin Kosnik <bkoz@redhat.com> + + * libsupc++/del_op.cc: Include c++config.h first. + * libsupc++/eh_alloc.cc: Same. + * libsupc++/new_opv.cc: Same. + * libsupc++/eh_throw.cc: Same. + * libsupc++/new_op.cc: Same. + * libsupc++/del_opv.cc: Same. + * libsupc++/eh_catch.cc: Same. + * libsupc++/guard.cc: Same. + * libsupc++/del_opnt.cc: Same. + * libsupc++/eh_exception.cc: Same. + * libsupc++/new_opvnt.cc: Same. + * libsupc++/eh_term_handler.cc: Same. + * libsupc++/eh_personality.cc: Same. + * libsupc++/eh_call.cc: Same. + * libsupc++/new_opnt.cc: Same. + * libsupc++/del_opvnt.cc: Same. + +2005-11-21 Benjamin Kosnik <bkoz@redhat.com> + + * src/Makefile.am (LTCXXCOMPILE): CXXFLAGS last. + * libsupc++/Makefile.am: Same. + * src/Makefile.in: Regenerate. + * libsupc++/Makefile.in: Same. + +2005-11-21 Paolo Carlini <pcarlini@suse.de> + + * include/ext/sso_string_base.h: Minor formatting and stylistic fixes. + (__sso_string_base<>::_M_get_allocator): Return by const ref. + * include/ext/rc_string_base.h: Likewise. + (__rc_string_base<>::_M_get_allocator): Return by const ref. + (__rc_string_base<>::_M_dispose): Take void, use _M_get_allocator. + (__rc_string_base<>::_M_grab): Take one alloc, use _M_get_allocator. + (__rc_string_base<>::~__rc_string_base, + __rc_string_base(const __rc_string_base&), _M_assign, _M_reserve, + _M_mutate): Adjust. + * include/ext/vstring_util.h: Minor stylistic fixes. + +2005-11-18 Paolo Carlini <pcarlini@suse.de> + + * include/ext/rc_string_base.h (__rc_string_base<>::_Rep): Avoid the + anonymous struct extension, adjust everywhere. + + * include/ext/rc_string_base.h (__rc_string_base<>::_S_empty_rep()): + Just use a static member. + (__rc_string_base<>::__rc_string_base(), _S_construct): Adjust. + + * include/ext/rc_string_base.h (__rc_string_base<>::_Rep): Use + anonymous union together with _CharT to fix alignment issues, + rebind to _Rep and rename _Raw_alloc to _Rep_alloc_type. + (__rc_string_base<>::_Rep::_S_create, _M_destroy): Adjust consistently. + + * include/ext/vstring_util.h (__is_null_p): Move inside struct + __vstring_utility as static _S_is_null_pointer. + * include/ext/sso_string.h + (__sso_string_base<>::_M_construct(std::forward_iterator_tag): Adjust. + * include/ext/rc_string_base.h + (__rc_string_base<>::_S_construct(std::forward_iterator_tag): Likewise. + + Implement Option 3 of DR 431 for ext/vstring - both available bases. + * include/bits/cpp_type_traits.h (struct __is_empty): Add. + * include/ext/vstring.h (__versa_string<>::swap): Delegate to + this->_M_swap. + * include/ext/vstring.tcc (__versa_string<>::swap): Remove. + * include/ext/vstring_util.h (struct __vstring_utility<>): Add struct + _Alloc_hider<>, augmented of allocator swapping facility, specialized + to nop for empty allocators. + * include/ext/rc_string_base.h (__rc_string_base<>::_M_swap): Use it. + (__rc_string_base<>::_M_is_leaked, _M_set_sharable): Change to private. + * include/ext/sso_string_base.h (__sso_string_base<>::_M_swap): + Likewise. + (__sso_string_base<>::_M_is_leaked, _M_set_sharable): Remove, unused. + * include/ext/rc_string_base.h (__rc_string_base<>::_M_data(_CharT*): + Return void. + * include/ext/sso_string_base.h (__sso_string_base<>::_M_data(_CharT*): + Likewise. + +2005-11-17 Geoffrey Keating <geoffk@apple.com> + + * config/os/bsd/darwin/ppc-extra.ver: New. + * src/Makefile.am (libstdc++-symbol.ver): Move outside conditionals, + and make dependent on port symbol files. + (libstdc++-symbol.explist): Use the generated .ver file, not + the template. + * src/compatibility.cc [APPLE] (__eprintf): New. + * src/Makefile.in: Regenerate. + * configure.host (powerpc*-*-darwin*): Define + port_specific_symbol_files. + +2005-11-16 Nathan Sidwell <nathan@codesourcery.com> + + * libsupc++/eh_arm.cc (__cxa_begin_cleanup): Remember a + foreign exception too. + (__gnu_end_cleanup): Recover a foreign exception too. + * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Cope + with forced unwinding. + * libsupc++/eh_throw.cc (__cxxabiv1::__cxa_rethrow): Use + _Unwind_Resume_or_Rethrow for ARM EABI. + 2005-11-14 Geoffrey Keating <geoffk@apple.com> * acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Don't check for diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in index 5f33b3f4627..a6459d533bf 100644 --- a/libstdc++-v3/Makefile.in +++ b/libstdc++-v3/Makefile.in @@ -45,11 +45,12 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \ $(top_srcdir)/scripts/testsuite_flags.in ChangeLog subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index daf3acfbca9..f320a8ad9b1 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -1705,8 +1705,8 @@ EOF rm -f conftest* fi - # This is a tad weird, for hysterical raisins. We have to map enable/disable - # to two different models. + # This is a tad weird, for hysterical raisins. We have to map + # enable/disable to two different models. case $enable_sjlj_exceptions in yes) AC_DEFINE(_GLIBCXX_SJLJ_EXCEPTIONS, 1, @@ -1924,5 +1924,6 @@ AC_DEFUN([AC_LC_MESSAGES], [ ]) ]) +# Macros from the top-level gcc directory. +m4_include([../config/tls.m4]) -dnl vim:et:ts=2:sw=2 diff --git a/libstdc++-v3/aclocal.m4 b/libstdc++-v3/aclocal.m4 index 757e1cc3e69..8f4ca5225c6 100644 --- a/libstdc++-v3/aclocal.m4 +++ b/libstdc++-v3/aclocal.m4 @@ -638,6 +638,7 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR +m4_include([../config/enable.m4]) m4_include([../config/lead-dot.m4]) m4_include([../config/no-executables.m4]) m4_include([../libtool.m4]) diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index 3815f4c7d5f..8d4f1bf0dc4 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -355,6 +355,9 @@ /* Define to 1 if you have the `tanl' function. */ #undef HAVE_TANL +/* Define to 1 if the target supports thread-local storage. */ +#undef HAVE_TLS + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 4b2b0136f53..9629a150902 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -890,6 +890,8 @@ Optional Features: --enable-fully-dynamic-string do not put empty strings in per-process static memory [default=no] + _g_switchUse thread-local storage + [default=yes] --enable-symvers=STYLE enables symbol versioning of the shared library [default=yes] --enable-version-specific-runtime-libs @@ -4459,7 +4461,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 4462 "configure"' > conftest.$ac_ext + echo '#line 4464 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -5079,7 +5081,7 @@ fi; # # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style. cat > conftest.$ac_ext << EOF -#line 5082 "configure" +#line 5084 "configure" struct S { ~S(); }; void bar(); void foo() @@ -5107,8 +5109,8 @@ EOF rm -f conftest* fi - # This is a tad weird, for hysterical raisins. We have to map enable/disable - # to two different models. + # This is a tad weird, for hysterical raisins. We have to map + # enable/disable to two different models. case $enable_sjlj_exceptions in yes) @@ -29995,6 +29997,135 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + # For TLS support. + + # Check whether --enable-tls or --disable-tls was given. +if test "${enable_tls+set}" = set; then + enableval="$enable_tls" + + case "$enableval" in + yes|no) ;; + *) { { echo "$as_me:$LINENO: error: Argument to enable/disable tls must be yes or no" >&5 +echo "$as_me: error: Argument to enable/disable tls must be yes or no" >&2;} + { (exit 1); exit 1; }; } ;; + esac + +else + enable_tls=yes +fi; + + echo "$as_me:$LINENO: checking whether the target supports thread-local storage" >&5 +echo $ECHO_N "checking whether the target supports thread-local storage... $ECHO_C" >&6 +if test "${have_tls+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if test "$cross_compiling" = yes; then + cat >conftest.$ac_ext <<_ACEOF +__thread int foo; +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + have_tls=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +have_tls=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +else + cat >conftest.$ac_ext <<_ACEOF +__thread int a; int b; int main() { return a = b; } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + save_LDFLAGS="$LDFLAGS" + LDFLAGS="-static $LDFLAGS" + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +__thread int a; int b; int main() { return a = b; } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + have_tls=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +have_tls=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + LDFLAGS="$save_LDFLAGS" +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +have_tls=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $have_tls" >&5 +echo "${ECHO_T}$have_tls" >&6 + if test "$enable_tls $have_tls" = "yes yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TLS 1 +_ACEOF + + fi + if test "${ac_cv_header_locale_h+set}" = set; then echo "$as_me:$LINENO: checking for locale.h" >&5 diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 3ed8be996b8..49ab1b8165b 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -158,6 +158,9 @@ if $GLIBCXX_IS_NATIVE; then # For LFS support. GLIBCXX_CHECK_LFS + # For TLS support. + GCC_CHECK_TLS + AC_LC_MESSAGES AC_TRY_COMPILE( diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index c387924dc25..e22897ca90c 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/fragment.am subdir = include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) CONFIG_HEADER = $(top_builddir)/config.h diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h index 4e78af5fa81..93cb4f5fb15 100644 --- a/libstdc++-v3/include/bits/cpp_type_traits.h +++ b/libstdc++-v3/include/bits/cpp_type_traits.h @@ -404,7 +404,6 @@ namespace std __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>) }; }; - } // namespace std #endif //_CPP_TYPE_TRAITS_H diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index 714f4e18e6f..949accd60f2 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -348,10 +348,7 @@ namespace _GLIBCXX_STD */ iterator insert(iterator __position, const value_type& __x) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.insert_equal((_Rep_iterator&)__position, __x); - } + { return _M_t.insert_equal(__position, __x); } /** * @brief A template function that attemps to insert a range of elements. @@ -382,10 +379,7 @@ namespace _GLIBCXX_STD */ iterator erase(iterator __position) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.erase((_Rep_iterator&)__position); - } + { return _M_t.erase(__position); } /** * @brief Erases elements according to the provided key. @@ -420,10 +414,7 @@ namespace _GLIBCXX_STD */ iterator erase(iterator __first, iterator __last) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); - } + { return _M_t.erase(__first, __last); } /** * Erases all elements in a %multiset. Note that this function only diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index 80499358bc4..b291478ebba 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -358,10 +358,7 @@ namespace _GLIBCXX_STD */ iterator insert(iterator __position, const value_type& __x) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.insert_unique((_Rep_iterator&)__position, __x); - } + { return _M_t.insert_unique(__position, __x); } /** * @brief A template function that attemps to insert a range of elements. @@ -372,9 +369,9 @@ namespace _GLIBCXX_STD * Complexity similar to that of the range constructor. */ template<class _InputIterator> - void - insert(_InputIterator __first, _InputIterator __last) - { _M_t.insert_unique(__first, __last); } + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Return type of container::erase(iterator) differs for @@ -391,10 +388,7 @@ namespace _GLIBCXX_STD */ iterator erase(iterator __position) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.erase((_Rep_iterator&)__position); - } + { return _M_t.erase(__position); } /** * @brief Erases elements according to the provided key. @@ -408,7 +402,8 @@ namespace _GLIBCXX_STD * in any way. Managing the pointer is the user's responsibilty. */ size_type - erase(const key_type& __x) { return _M_t.erase(__x); } + erase(const key_type& __x) + { return _M_t.erase(__x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Return type of container::erase(iterator) differs for @@ -428,10 +423,7 @@ namespace _GLIBCXX_STD */ iterator erase(iterator __first, iterator __last) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); - } + { return _M_t.erase(__first, __last); } /** * Erases all elements in a %set. Note that this function only erases diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 4d1fd401621..742d1e97194 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -546,6 +546,10 @@ namespace std iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + const_iterator + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __y, + const value_type& __v); + _Link_type _M_copy(_Const_Link_type __x, _Link_type __p); @@ -654,9 +658,15 @@ namespace std iterator insert_unique(iterator __position, const value_type& __x); + const_iterator + insert_unique(const_iterator __position, const value_type& __x); + iterator insert_equal(iterator __position, const value_type& __x); + const_iterator + insert_equal(const_iterator __position, const value_type& __x); + template<typename _InputIterator> void insert_unique(_InputIterator __first, _InputIterator __last); @@ -668,12 +678,18 @@ namespace std iterator erase(iterator __position); + const_iterator + erase(const_iterator __position); + size_type erase(const key_type& __x); iterator erase(iterator __first, iterator __last); + const_iterator + erase(const_iterator __first, const_iterator __last); + void erase(const key_type* __first, const key_type* __last); @@ -817,6 +833,25 @@ namespace std template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v) + { + bool __insert_left = (__x != 0 || __p == _M_end() + || _M_impl._M_key_compare()(_KeyOfValue()(__v), + _S_key(__p))); + + _Link_type __z = _M_create_node(__v); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, + const_cast<_Base_ptr>(__p), + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return const_iterator(__z); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: insert_equal(const _Val& __v) @@ -963,6 +998,63 @@ namespace std template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_unique(const_iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && _M_impl._M_key_compare()(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(insert_unique(__v).first); + } + else if (_M_impl._M_key_compare()(_KeyOfValue()(__v), + _S_key(__position._M_node))) + { + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (_M_impl._M_key_compare()(_S_key((--__before)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return const_iterator(insert_unique(__v).first); + } + else if (_M_impl._M_key_compare()(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (_M_impl._M_key_compare()(_KeyOfValue()(__v), + _S_key((++__after)._M_node))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return const_iterator(insert_unique(__v).first); + } + else + return __position; // Equivalent keys. + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: insert_equal(iterator __position, const _Val& __v) @@ -1015,6 +1107,60 @@ namespace std } } + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_equal(const_iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && !_M_impl._M_key_compare()(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(insert_equal(__v)); + } + else if (!_M_impl._M_key_compare()(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (!_M_impl._M_key_compare()(_KeyOfValue()(__v), + _S_key((--__before)._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return const_iterator(insert_equal(__v)); + } + else + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (!_M_impl._M_key_compare()(_S_key((++__after)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return const_iterator(insert_equal(__v)); + } + } + template<typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc> template<class _II> @@ -1029,13 +1175,13 @@ namespace std template<typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc> template<class _II> - void - _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: - insert_unique(_II __first, _II __last) - { - for (; __first != __last; ++__first) - insert_unique(end(), *__first); - } + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + insert_unique(_II __first, _II __last) + { + for (; __first != __last; ++__first) + insert_unique(end(), *__first); + } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> @@ -1057,6 +1203,24 @@ namespace std template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> + inline + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __position) + { + const_iterator __ret = __position; + ++__ret; + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase + (const_cast<_Base_ptr>(__position._M_node), + this->_M_impl._M_header)); + destroy_node(__y); + --_M_impl._M_node_count; + return __ret; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: erase(const _Key& __x) @@ -1135,6 +1299,20 @@ namespace std template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __first, const_iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) + __first = erase(__first); + return __last; + } + + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: erase(const _Key* __first, const _Key* __last) diff --git a/libstdc++-v3/libmath/Makefile.in b/libstdc++-v3/libmath/Makefile.in index be902635db1..665d26bfef0 100644 --- a/libstdc++-v3/libmath/Makefile.in +++ b/libstdc++-v3/libmath/Makefile.in @@ -40,11 +40,12 @@ target_triplet = @target@ subdir = libmath DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) CONFIG_HEADER = $(top_builddir)/config.h diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am index 161a4a02d83..2c749cb0dbe 100644 --- a/libstdc++-v3/libsupc++/Makefile.am +++ b/libstdc++-v3/libsupc++/Makefile.am @@ -1,6 +1,7 @@ ## Makefile for the GNU C++ Support library. ## -## Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 +## Free Software Foundation, Inc. ## ## Process this file with automake to produce Makefile.in. ## @@ -136,7 +137,7 @@ cp-demangle.o: cp-demangle.c # CXX undo the affect of disable-shared. LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) # 3) We'd have a problem when building the shared libstdc++ object if # the rules automake generates would be used. We cannot allow g++ to diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in index 275c4a74673..868725e8237 100644 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -42,11 +42,12 @@ DIST_COMMON = $(glibcxxinstall_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/fragment.am subdir = libsupc++ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) CONFIG_HEADER = $(top_builddir)/config.h @@ -397,7 +398,7 @@ LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared --mode=compile $(CC) \ # CXX undo the affect of disable-shared. LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared \ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) # 3) We'd have a problem when building the shared libstdc++ object if diff --git a/libstdc++-v3/libsupc++/del_op.cc b/libstdc++-v3/libsupc++/del_op.cc index 194a87aa65e..93f4aa8373c 100644 --- a/libstdc++-v3/libsupc++/del_op.cc +++ b/libstdc++-v3/libsupc++/del_op.cc @@ -28,8 +28,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" #include <bits/c++config.h> +#include "new" #if _GLIBCXX_HOSTED #include <cstdlib> #endif diff --git a/libstdc++-v3/libsupc++/del_opnt.cc b/libstdc++-v3/libsupc++/del_opnt.cc index b03a0798133..1aa25d76ba5 100644 --- a/libstdc++-v3/libsupc++/del_opnt.cc +++ b/libstdc++-v3/libsupc++/del_opnt.cc @@ -28,8 +28,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" #include <bits/c++config.h> +#include "new" extern "C" void free (void *); diff --git a/libstdc++-v3/libsupc++/del_opv.cc b/libstdc++-v3/libsupc++/del_opv.cc index 98aaa9b2736..9a08afbb54b 100644 --- a/libstdc++-v3/libsupc++/del_opv.cc +++ b/libstdc++-v3/libsupc++/del_opv.cc @@ -28,8 +28,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" #include <bits/c++config.h> +#include "new" _GLIBCXX_WEAK_DEFINITION void operator delete[] (void *ptr) throw () diff --git a/libstdc++-v3/libsupc++/del_opvnt.cc b/libstdc++-v3/libsupc++/del_opvnt.cc index b9c81ce74e0..4dbe48931cf 100644 --- a/libstdc++-v3/libsupc++/del_opvnt.cc +++ b/libstdc++-v3/libsupc++/del_opvnt.cc @@ -28,8 +28,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" #include <bits/c++config.h> +#include "new" _GLIBCXX_WEAK_DEFINITION void operator delete[] (void *ptr, const std::nothrow_t&) throw () diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc index 3577920e0f3..5a0d50c8058 100644 --- a/libstdc++-v3/libsupc++/eh_alloc.cc +++ b/libstdc++-v3/libsupc++/eh_alloc.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Allocate exception objects. -// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -30,6 +30,7 @@ // This is derived from the C++ ABI for IA-64. Where we diverge // for cross-architecture compatibility are noted with "@@@". +#include <bits/c++config.h> #include <cstdlib> #if _GLIBCXX_HOSTED #include <cstring> @@ -37,7 +38,6 @@ #include <climits> #include <exception> #include "unwind-cxx.h" -#include "bits/c++config.h" #include "bits/gthr.h" #if _GLIBCXX_HOSTED diff --git a/libstdc++-v3/libsupc++/eh_arm.cc b/libstdc++-v3/libsupc++/eh_arm.cc index d87d82ad5a0..269b2ec95af 100644 --- a/libstdc++-v3/libsupc++/eh_arm.cc +++ b/libstdc++-v3/libsupc++/eh_arm.cc @@ -89,20 +89,31 @@ __cxa_begin_cleanup(_Unwind_Exception* ue_header) { __cxa_eh_globals *globals = __cxa_get_globals(); __cxa_exception *header = __get_exception_header_from_ue(ue_header); + bool native = __is_gxx_exception_class(header->unwindHeader.exception_class); - if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) + + if (native) { - // TODO: cleanups with foreign exceptions. - return false; + header->propagationCount++; + // Add it to the chain if this is the first time we've seen this + // exception. + if (header->propagationCount == 1) + { + header->nextPropagatingException = globals->propagatingExceptions; + globals->propagatingExceptions = header; + } } - header->propagationCount++; - // Add it to the chain if this is the first time we've seen this exception. - if (header->propagationCount == 1) + else { - header->nextPropagatingException = globals->propagatingExceptions; + // Remember the exception object, so end_cleanup can return it. + // These cannot be stacked, so we must abort if we already have + // a propagating exception. + if (globals->propagatingExceptions) + std::terminate (); globals->propagatingExceptions = header; } - return true; + + return !native; } // Do the work for __cxa_end_cleanup. Returns the currently propagating @@ -119,13 +130,19 @@ __gnu_end_cleanup(void) if (!header) std::terminate(); - header->propagationCount--; - if (header->propagationCount == 0) + if (__is_gxx_exception_class(header->unwindHeader.exception_class)) { - // Remove exception from chain. - globals->propagatingExceptions = header->nextPropagatingException; - header->nextPropagatingException = NULL; + header->propagationCount--; + if (header->propagationCount == 0) + { + // Remove exception from chain. + globals->propagatingExceptions = header->nextPropagatingException; + header->nextPropagatingException = NULL; + } } + else + globals->propagatingExceptions = NULL; + return &header->unwindHeader; } diff --git a/libstdc++-v3/libsupc++/eh_call.cc b/libstdc++-v3/libsupc++/eh_call.cc index 4db8023fcdb..edf62188a6b 100644 --- a/libstdc++-v3/libsupc++/eh_call.cc +++ b/libstdc++-v3/libsupc++/eh_call.cc @@ -27,7 +27,6 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. - #include <bits/c++config.h> #include <cstdlib> #include <exception_defines.h> diff --git a/libstdc++-v3/libsupc++/eh_catch.cc b/libstdc++-v3/libsupc++/eh_catch.cc index d84584029be..77b8a82dd16 100644 --- a/libstdc++-v3/libsupc++/eh_catch.cc +++ b/libstdc++-v3/libsupc++/eh_catch.cc @@ -27,7 +27,6 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. - #include <cstdlib> #include "unwind-cxx.h" diff --git a/libstdc++-v3/libsupc++/eh_exception.cc b/libstdc++-v3/libsupc++/eh_exception.cc index fc78d9be9c2..81d7e70bcf3 100644 --- a/libstdc++-v3/libsupc++/eh_exception.cc +++ b/libstdc++-v3/libsupc++/eh_exception.cc @@ -28,7 +28,6 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. - #include "typeinfo" #include "exception" #include "unwind-cxx.h" diff --git a/libstdc++-v3/libsupc++/eh_globals.cc b/libstdc++-v3/libsupc++/eh_globals.cc index 00465dedf93..9b7e916716d 100644 --- a/libstdc++-v3/libsupc++/eh_globals.cc +++ b/libstdc++-v3/libsupc++/eh_globals.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Manage the thread-local exception globals. -// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -27,101 +27,127 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. - +#include <bits/c++config.h> #include <exception> #include <cstdlib> +#include "cxxabi.h" #include "unwind-cxx.h" -#include "bits/c++config.h" #include "bits/gthr.h" using namespace __cxxabiv1; +#if _GLIBCXX_HAVE_TLS + +namespace __gnu_internal +{ + using namespace abi; + using namespace std; + + __cxa_eh_globals* + get_global() throw() + { + static __thread __cxa_eh_globals global; + return &global; + } +} + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals_fast() throw() +{ return __gnu_internal::get_global(); } + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals() throw() +{ return __gnu_internal::get_global(); } + + +#else // Single-threaded fallback buffer. -static __cxa_eh_globals globals_static; +static __cxa_eh_globals eh_globals; #if __GTHREADS -static __gthread_key_t globals_key; -static int use_thread_key = -1; static void -get_globals_dtor (void *ptr) +eh_globals_dtor(void* ptr) { if (ptr) { - __cxa_exception *exn, *next; - exn = ((__cxa_eh_globals *) ptr)->caughtExceptions; + __cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr); + __cxa_exception* exn = g->caughtExceptions; + __cxa_exception* next; while (exn) { next = exn->nextException; - _Unwind_DeleteException (&exn->unwindHeader); + _Unwind_DeleteException(&exn->unwindHeader); exn = next; } - std::free (ptr); + std::free(ptr); } } -static void -get_globals_init () +struct __eh_globals_init { - use_thread_key = - (__gthread_key_create (&globals_key, get_globals_dtor) == 0); -} - -static void -get_globals_init_once () + __gthread_key_t _M_key; + bool _M_init; + + __eh_globals_init() : _M_init(false) + { + if (__gthread_active_p()) + _M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0; + } + + ~__eh_globals_init() + { + if (_M_init) + __gthread_key_delete(_M_key); + } +}; + +static __eh_globals_init init; + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals_fast() throw() { - static __gthread_once_t once = __GTHREAD_ONCE_INIT; - if (__gthread_once (&once, get_globals_init) != 0 - || use_thread_key < 0) - use_thread_key = 0; + __cxa_eh_globals* g; + if (init._M_init) + g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key)); + else + g = &eh_globals; + return g; } -#endif -extern "C" __cxa_eh_globals * -__cxxabiv1::__cxa_get_globals_fast () throw() +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals() throw() { -#if __GTHREADS - if (use_thread_key) - return (__cxa_eh_globals *) __gthread_getspecific (globals_key); + __cxa_eh_globals* g; + if (init._M_init) + { + g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key)); + if (!g) + { + void* v = std::malloc(sizeof(__cxa_eh_globals)); + if (v == 0 || __gthread_setspecific(init._M_key, v) != 0) + std::terminate(); + g = static_cast<__cxa_eh_globals*>(v); + g->caughtExceptions = 0; + g->uncaughtExceptions = 0; + } + } else - return &globals_static; -#else - return &globals_static; -#endif + g = &eh_globals; + return g; } -extern "C" __cxa_eh_globals * -__cxxabiv1::__cxa_get_globals () throw() -{ -#if __GTHREADS - __cxa_eh_globals *g; - - if (use_thread_key == 0) - return &globals_static; +#else - if (use_thread_key < 0) - { - get_globals_init_once (); +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals_fast() throw() +{ return &eh_globals; } - // Make sure use_thread_key got initialized. - if (use_thread_key == 0) - return &globals_static; - } +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals() throw() +{ return &eh_globals; } - g = (__cxa_eh_globals *) __gthread_getspecific (globals_key); - if (! g) - { - if ((g = (__cxa_eh_globals *) - std::malloc (sizeof (__cxa_eh_globals))) == 0 - || __gthread_setspecific (globals_key, (void *) g) != 0) - std::terminate (); - g->caughtExceptions = 0; - g->uncaughtExceptions = 0; - } +#endif - return g; -#else - return &globals_static; #endif -} diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index 6205851a2c4..917a397569c 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -27,7 +27,6 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. - #include <bits/c++config.h> #include <cstdlib> #include <exception_defines.h> @@ -369,7 +368,7 @@ PERSONALITY_FUNCTION (int version, #ifdef __ARM_EABI_UNWINDER__ _Unwind_Action actions; - switch (state) + switch (state & _US_ACTION_MASK) { case _US_VIRTUAL_UNWIND_FRAME: actions = _UA_SEARCH_PHASE; @@ -377,7 +376,8 @@ PERSONALITY_FUNCTION (int version, case _US_UNWIND_FRAME_STARTING: actions = _UA_CLEANUP_PHASE; - if (ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) + if (!(state & _US_FORCE_UNWIND) + && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) actions |= _UA_HANDLER_FRAME; break; @@ -388,6 +388,7 @@ PERSONALITY_FUNCTION (int version, default: abort(); } + actions |= state & _US_FORCE_UNWIND; // We don't know which runtime we're working with, so can't check this. // However the ABI routines hide this from us, and we don't actually need @@ -523,13 +524,13 @@ PERSONALITY_FUNCTION (int version, // exception class, there's no exception type. // ??? What to do about GNU Java and GNU Ada exceptions. -#ifdef __ARM_EABI_UNWINDER__ - throw_type = ue_header; -#else if ((actions & _UA_FORCE_UNWIND) || foreign_exception) throw_type = 0; else +#ifdef __ARM_EABI_UNWINDER__ + throw_type = ue_header; +#else throw_type = xh->exceptionType; #endif @@ -613,7 +614,6 @@ PERSONALITY_FUNCTION (int version, install_context: -#ifndef __ARM_EABI_UNWINDER__ // We can't use any of the cxa routines with foreign exceptions, // because they all expect ue_header to be a struct __cxa_exception. // So in that case, call terminate or unexpected directly. @@ -631,7 +631,6 @@ PERSONALITY_FUNCTION (int version, } } else -#endif { if (found_type == found_terminate) __cxa_call_terminate(ue_header); diff --git a/libstdc++-v3/libsupc++/eh_term_handler.cc b/libstdc++-v3/libsupc++/eh_term_handler.cc index 66025ed6a78..b3914974931 100644 --- a/libstdc++-v3/libsupc++/eh_term_handler.cc +++ b/libstdc++-v3/libsupc++/eh_term_handler.cc @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "unwind-cxx.h" #include <bits/c++config.h> +#include "unwind-cxx.h" /* We default to the talkative, informative handler in a normal hosted library. This pulls in the demangler, the dyn-string utilities, and diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index 8b04f395c87..b405f8f7c64 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -27,7 +27,6 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. - #include <bits/c++config.h> #include "unwind-cxx.h" @@ -97,7 +96,7 @@ __cxxabiv1::__cxa_rethrow () #ifdef _GLIBCXX_SJLJ_EXCEPTIONS _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); #else -#if defined(_LIBUNWIND_STD_ABI) || defined (__ARM_EABI_UNWINDER__) +#if defined(_LIBUNWIND_STD_ABI) _Unwind_RaiseException (&header->unwindHeader); #else _Unwind_Resume_or_Rethrow (&header->unwindHeader); diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc index e75dc42a428..e7fe2b6e7b9 100644 --- a/libstdc++-v3/libsupc++/guard.cc +++ b/libstdc++-v3/libsupc++/guard.cc @@ -29,9 +29,9 @@ // Written by Mark Mitchell, CodeSourcery LLC, <mark@codesourcery.com> // Thread support written by Jason Merrill, Red Hat Inc. <jason@redhat.com> +#include <bits/c++config.h> #include <cxxabi.h> #include <exception> -#include <bits/c++config.h> #include <bits/gthr.h> #include <bits/atomicity.h> diff --git a/libstdc++-v3/libsupc++/new_op.cc b/libstdc++-v3/libsupc++/new_op.cc index 76ede3097ea..8059d1d110c 100644 --- a/libstdc++-v3/libsupc++/new_op.cc +++ b/libstdc++-v3/libsupc++/new_op.cc @@ -29,10 +29,10 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" +#include <bits/c++config.h> #include <cstdlib> #include <exception_defines.h> -#include <bits/c++config.h> +#include "new" using std::new_handler; using std::bad_alloc; diff --git a/libstdc++-v3/libsupc++/new_opnt.cc b/libstdc++-v3/libsupc++/new_opnt.cc index 4a44bc79d49..65b79a355f0 100644 --- a/libstdc++-v3/libsupc++/new_opnt.cc +++ b/libstdc++-v3/libsupc++/new_opnt.cc @@ -27,9 +27,9 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" -#include <exception_defines.h> #include <bits/c++config.h> +#include <exception_defines.h> +#include "new" using std::new_handler; using std::bad_alloc; diff --git a/libstdc++-v3/libsupc++/new_opv.cc b/libstdc++-v3/libsupc++/new_opv.cc index 5f761353280..e40565bada7 100644 --- a/libstdc++-v3/libsupc++/new_opv.cc +++ b/libstdc++-v3/libsupc++/new_opv.cc @@ -28,8 +28,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" #include <bits/c++config.h> +#include "new" _GLIBCXX_WEAK_DEFINITION void* operator new[] (std::size_t sz) throw (std::bad_alloc) diff --git a/libstdc++-v3/libsupc++/new_opvnt.cc b/libstdc++-v3/libsupc++/new_opvnt.cc index f681e33e806..7d59d43c33f 100644 --- a/libstdc++-v3/libsupc++/new_opvnt.cc +++ b/libstdc++-v3/libsupc++/new_opvnt.cc @@ -28,8 +28,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include "new" #include <bits/c++config.h> +#include "new" _GLIBCXX_WEAK_DEFINITION void* operator new[] (std::size_t sz, const std::nothrow_t& nothrow) throw() diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in index ff98f5abf47..500a6d235dc 100644 --- a/libstdc++-v3/po/Makefile.in +++ b/libstdc++-v3/po/Makefile.in @@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/fragment.am subdir = po ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) CONFIG_HEADER = $(top_builddir)/config.h diff --git a/libstdc++-v3/scripts/create_testsuite_files b/libstdc++-v3/scripts/create_testsuite_files index 4b9a41fc5fc..d5305236140 100755 --- a/libstdc++-v3/scripts/create_testsuite_files +++ b/libstdc++-v3/scripts/create_testsuite_files @@ -35,7 +35,9 @@ dlist=`echo [0-9][0-9]*` for d in [a-z]*; do test -d $d && dlist="$dlist $d" done -find $dlist "(" -type f -o -type l ")" -name "*.cc" -print | sort > $tmp.1 +find $dlist "(" -type f -o -type l ")" -name "*.cc" -print > $tmp.01 +find $dlist "(" -type f -o -type l ")" -name "*.c" -print > $tmp.02 +cat $tmp.01 $tmp.02 | sort > $tmp.1 if test ! -s "$tmp.1"; then exit 1 fi diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index 20d3fda9ce3..993cf21234f 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -32,6 +32,7 @@ if ENABLE_SYMVERS_GNU version_arg = -Wl,--version-script=libstdc++-symbol.ver version_dep = libstdc++-symbol.ver libstdc++-symbol.ver: ${glibcxx_srcdir}/$(SYMVER_MAP) + cp ${glibcxx_srcdir}/$(SYMVER_MAP) ./libstdc++-symbol.ver if test "x$(port_specific_symbol_files)" != x; then \ sed -n '1,/DO NOT DELETE/p' $@ > tmp.top; \ @@ -39,6 +40,7 @@ libstdc++-symbol.ver: ${glibcxx_srcdir}/$(SYMVER_MAP) cat tmp.top $(port_specific_symbol_files) tmp.bottom > $@; \ rm tmp.top tmp.bottom; \ fi + else if ENABLE_SYMVERS_DARWIN_EXPORT version_arg = -Wl,-exported_symbols_list,libstdc++-symbol.explist @@ -172,7 +174,6 @@ libstdc___la_DEPENDENCIES = ${version_dep} $(libstdc___la_LIBADD) libstdc___la_LDFLAGS = \ -version-info $(libtool_VERSION) ${version_arg} -lm - # Use special rules for the deprecated source files so that they find # deprecated include files. GLIBCXX_INCLUDE_DIR=$(glibcxx_builddir)/include @@ -220,7 +221,7 @@ AM_CXXFLAGS = \ # CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to # attempt to infer which configuration to use LTCXXCOMPILE = $(LIBTOOL) --tag CXX --mode=compile $(CXX) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) # 3) We'd have a problem when building the shared libstdc++ object if # the rules automake generates would be used. We cannot allow g++ to diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index cf4296d3382..f958996627c 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/fragment.am subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) CONFIG_HEADER = $(top_builddir)/config.h @@ -403,7 +404,7 @@ AM_CXXFLAGS = \ # CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to # attempt to infer which configuration to use LTCXXCOMPILE = $(LIBTOOL) --tag CXX --mode=compile $(CXX) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) # 3) We'd have a problem when building the shared libstdc++ object if @@ -675,6 +676,7 @@ uninstall-am: uninstall-info-am uninstall-toolexeclibLTLIBRARIES uninstall-toolexeclibLTLIBRARIES @ENABLE_SYMVERS_GNU_TRUE@libstdc++-symbol.ver: ${glibcxx_srcdir}/$(SYMVER_MAP) + @ENABLE_SYMVERS_GNU_TRUE@ cp ${glibcxx_srcdir}/$(SYMVER_MAP) ./libstdc++-symbol.ver @ENABLE_SYMVERS_GNU_TRUE@ if test "x$(port_specific_symbol_files)" != x; then \ @ENABLE_SYMVERS_GNU_TRUE@ sed -n '1,/DO NOT DELETE/p' $@ > tmp.top; \ diff --git a/libstdc++-v3/testsuite/19_diagnostics/23591_thread-1.c b/libstdc++-v3/testsuite/19_diagnostics/23591_thread-1.c new file mode 100644 index 00000000000..8c953eaed0e --- /dev/null +++ b/libstdc++-v3/testsuite/19_diagnostics/23591_thread-1.c @@ -0,0 +1,63 @@ +// { dg-require-sharedlib "" } +// { dg-options "-g -O2 -pthread -ldl -x c" { target *-*-linux* } } + +// Copyright (C) 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +#include <pthread.h> +#include <dlfcn.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +// NB: This must be compiled and linked as a "C" executable. +static void* run(void* arg) +{ + typedef void (*function_type) (void); + void* lib; + void (*cb)(); + + lib = dlopen("./testsuite_shared.so", RTLD_NOW); + if (lib == NULL) + { + printf("dlopen failed: %s\n", strerror(errno)); + return NULL; + } + cb = (function_type) dlsym(lib, "try_throw_exception"); + if (cb == NULL) + { + printf("dlsym failed: %s\n", strerror(errno)); + return NULL; + } + cb(); + dlclose(lib); + return NULL; +} + +// libstdc++/23591 +int main(void) +{ + pthread_t pt; + + if (pthread_create(&pt, NULL, &run, NULL) != 0) + return 1; + if (pthread_join(pt, NULL) != 0) + return 1; + + return 0; +} diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in index fb1b33c6b84..b01e53050e0 100644 --- a/libstdc++-v3/testsuite/Makefile.in +++ b/libstdc++-v3/testsuite/Makefile.in @@ -40,11 +40,12 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/fragment.am subdir = testsuite ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/lead-dot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/no-executables.m4 \ $(top_srcdir)/../libtool.m4 $(top_srcdir)/crossconfig.m4 \ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) CONFIG_HEADER = $(top_builddir)/config.h diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc b/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc index f2243657a5d..1df94b7c666 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc @@ -50,7 +50,7 @@ check_dlsym(void*& h) typedef void (*function_type) (void); function_type fn; - fn = reinterpret_cast<function_type>(dlsym(h, "foo")); + fn = reinterpret_cast<function_type>(dlsym(h, "try_allocation")); try { diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp index 0f10e6dff91..ee5111dfaf9 100644 --- a/libstdc++-v3/testsuite/lib/libstdc++.exp +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp @@ -266,14 +266,32 @@ proc libstdc++-dg-test { prog do_what extra_tool_flags } { # created or not. If it was, dg.exp will try to run it. remote_file build delete $output_file; } - default { + default { perror "$do_what: not a valid dg-do keyword" return "" } } + set options "" if { $extra_tool_flags != "" } { - lappend options "additional_flags=$extra_tool_flags" + verbose -log "extra_tool_flags are:" + verbose -log $extra_tool_flags + if { [string first "-x c" $extra_tool_flags ] != -1 } { + # Short-circut a bunch of complicated goo here for the + # special case of compiling a test file as a "C" file, not + # as C++: just use target_compile, instead of the usual + # gimmicks. + verbose -log "compiling and executing as C, not C++" + set compile_type "executable" + set output_file "./[file rootname [file tail $prog]].exe" + remote_file build delete $output_file; + lappend options "additional_flags=$extra_tool_flags" + set comp_output [target_compile "$prog" "$output_file" "$compile_type" $options]; + set comp_output [ prune_g++_output $comp_output ]; + return [list $comp_output $output_file] + } else { + lappend options "additional_flags=$extra_tool_flags" + } } # There is a libstdc++_compile made for us by default (via the tool- @@ -608,8 +626,7 @@ proc check_v3_target_debug_mode { } { set et_debug_mode 0 # Set up, compile, and execute a C++ test program that depends - # on correct ordering of static object destructors. This is - # indicative of the presence and use of __cxa_atexit. + # on debug mode working. set src debug_mode[pid].cc set exe debug_mode[pid].exe diff --git a/libstdc++-v3/testsuite/libstdc++-dg/normal.exp b/libstdc++-v3/testsuite/libstdc++-dg/normal.exp index 6ebe6b439ec..21bc3c1b915 100644 --- a/libstdc++-v3/testsuite/libstdc++-dg/normal.exp +++ b/libstdc++-v3/testsuite/libstdc++-dg/normal.exp @@ -1,4 +1,4 @@ -# Primary test file for libstdc++. +# Functional and regression tests in C++ for libstdc++. # Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. # @@ -61,6 +61,11 @@ if {[info exists tests_file] && [file exists $tests_file]} { # Find all the tests. foreach s $subdirs { set subdir_tests [find $s *.cc] + set subdir_tests_c [find $s *.c] + foreach e $subdir_tests_c { + lappend subdir_tests $e + } + # Filter out tests that should not be run. foreach t $subdir_tests { # The DejaGNU "find" procedure sometimes returns a list diff --git a/libstdc++-v3/testsuite/testsuite_shared.cc b/libstdc++-v3/testsuite/testsuite_shared.cc index a829fb47aa7..58803a2ae4f 100644 --- a/libstdc++-v3/testsuite/testsuite_shared.cc +++ b/libstdc++-v3/testsuite/testsuite_shared.cc @@ -17,11 +17,14 @@ // USA. #include <string> +#include <stdexcept> +#include <iostream> +#include <sstream> #include <ext/mt_allocator.h> // libstdc++/22309 extern "C" void -foo() +try_allocation() { typedef char value_t; @@ -34,3 +37,37 @@ foo() string_t s; s += "west beach, indiana dunes"; } + +// libstdc++/23591 +extern "C" void +try_throw_exception() +{ + try + { + throw std::bad_exception(); + } + catch (const std::exception& e) + { } +} + +extern "C" void +try_function_random_fail() +{ + long seed = lrand48(); + if (seed < 2000) + seed = 2000; + + { + std::ostringstream s; + s << "random_throw, seed: " << seed << std::endl; + std::cout << s.str(); + } + + while (--seed > 0) + { + try_throw_exception(); + } + + // Randomly throw. See if other threads cleanup. + throw std::bad_exception(); +} |