From d91ef9b080d6973de3f2a6851855a03b54743d52 Mon Sep 17 00:00:00 2001 From: dannysmith Date: Wed, 1 Nov 2006 06:23:12 +0000 Subject: [PATCH] * target.h (targetm.cxx.use_atexit_for_cxa_atexit): New target hook. * target-def.h: (TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT): Define default. * config/i386/mingw32.h (TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT): Override default. * doc/tm.texi (TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT): Document. * configure.ac (use_cxa_atexit): As a special case, don't test for libc definition of __cxa_atexit on mingw32 * configure: Regenerate. * config.gcc (i[34567]86-pc-mingw32): Default to enable__cxa_atexit=yes. cp * decl.c (get_atexit_node): Reference atexit, not __cxa_exit. if targetm.cxx.use_atexit_for cxa_atexit. (start_cleanup_fn): Likewise. (register_dtor_fn): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@118371 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 15 +++++++++++++++ gcc/config.gcc | 1 + gcc/config/i386/mingw32.h | 4 ++++ gcc/configure | 11 ++++++++++- gcc/configure.ac | 13 +++++++++++-- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 10 ++++++---- gcc/doc/tm.texi | 8 ++++++++ gcc/target-def.h | 5 +++++ gcc/target.h | 3 +++ 10 files changed, 70 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ab2d0d1e946..6332e06d05c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2006-11-01 Danny Smith + + * target.h (targetm.cxx.use_atexit_for_cxa_atexit): New target + hook. + * target-def.h: (TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT): Define + default. + * config/i386/mingw32.h (TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT): + Override default. + * doc/tm.texi (TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT): Document. + * configure.ac (use_cxa_atexit): As a special case, don't test + for libc definition of __cxa_atexit on mingw32 + * configure: Regenerate. + * config.gcc (i[34567]86-pc-mingw32): Default to + enable__cxa_atexit=yes. + 2006-11-01 Kaveh R. Ghazi * builtins.def (gamma, lgamma): Use ATTR_MATHFN_FPROUNDING_STORE. diff --git a/gcc/config.gcc b/gcc/config.gcc index bbe82f069c9..9ab3a659c6c 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1310,6 +1310,7 @@ i[34567]86-*-mingw32*) extra_options="${extra_options} i386/cygming.opt" extra_objs="winnt.o winnt-stubs.o" cxx_target_objs=winnt-cxx.o + default_use_cxa_atexit=yes case ${enable_threads} in "" | yes | win32) thread_file='win32' diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h index 6fd5d94cfd5..28c2fb9fbb8 100644 --- a/gcc/config/i386/mingw32.h +++ b/gcc/config/i386/mingw32.h @@ -112,3 +112,7 @@ do { \ /* mingw32 uses the -mthreads option to enable thread support. */ #undef GOMP_SELF_SPECS #define GOMP_SELF_SPECS "%{fopenmp: -mthreads}" + +/* mingw32 atexit function is safe to use in shared libraries. Use it + to register C++ static destructors. */ +#define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true diff --git a/gcc/configure b/gcc/configure index cbf94b59f80..49535d590f7 100755 --- a/gcc/configure +++ b/gcc/configure @@ -12428,7 +12428,14 @@ use_cxa_atexit=no if test x$enable___cxa_atexit = xyes || \ test x$enable___cxa_atexit = x -a x$default_use_cxa_atexit = xyes; then if test x$host = x$target; then - echo "$as_me:$LINENO: checking for __cxa_atexit" >&5 + case $host in + # mingw32 doesn't have __cxa_atexit but uses atexit registration + # keyed to flag_use_cxa_atexit + *-*-mingw32*) + use_cxa_atexit=yes + ;; + *) + echo "$as_me:$LINENO: checking for __cxa_atexit" >&5 echo $ECHO_N "checking for __cxa_atexit... $ECHO_C" >&6 if test "${ac_cv_func___cxa_atexit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -12524,6 +12531,8 @@ else echo "__cxa_atexit can't be enabled on this target" fi + :: + esac else # We can't check for __cxa_atexit when building a cross, so assume # it is available diff --git a/gcc/configure.ac b/gcc/configure.ac index 0b42531ff6d..7b571385ce4 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1429,8 +1429,17 @@ use_cxa_atexit=no if test x$enable___cxa_atexit = xyes || \ test x$enable___cxa_atexit = x -a x$default_use_cxa_atexit = xyes; then if test x$host = x$target; then - AC_CHECK_FUNC(__cxa_atexit,[use_cxa_atexit=yes], - [echo "__cxa_atexit can't be enabled on this target"]) + case $host in + # mingw32 doesn't have __cxa_atexit but uses atexit registration + # keyed to flag_use_cxa_atexit + *-*-mingw32*) + use_cxa_atexit=yes + ;; + *) + AC_CHECK_FUNC(__cxa_atexit,[use_cxa_atexit=yes], + [echo "__cxa_atexit can't be enabled on this target"]) + :: + esac else # We can't check for __cxa_atexit when building a cross, so assume # it is available diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index add6b2c3389..6e30ada4873 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2006-11-01 Danny Smith + + * decl.c (get_atexit_node): Reference atexit, not __cxa_exit. + if targetm.cxx.use_atexit_for cxa_atexit. + (start_cleanup_fn): Likewise. + (register_dtor_fn): Likewise. + 2006-09-25 Geoffrey Keating * decl2.c (cp_write_global_declarations): Rename from diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 66c34e418da..cc74908c152 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5348,7 +5348,7 @@ get_atexit_node (void) if (atexit_node) return atexit_node; - if (flag_use_cxa_atexit) + if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ()) { /* The declaration for `__cxa_atexit' is: @@ -5436,6 +5436,8 @@ start_cleanup_fn (void) tree parmtypes; tree fntype; tree fndecl; + bool use_cxa_atexit = flag_use_cxa_atexit + && !targetm.cxx.use_atexit_for_cxa_atexit (); push_to_top_level (); @@ -5448,7 +5450,7 @@ start_cleanup_fn (void) We'll just ignore it. After we implement the new calling convention for destructors, we can eliminate the use of additional cleanup functions entirely in the -fnew-abi case. */ - if (flag_use_cxa_atexit) + if (use_cxa_atexit) parmtypes = tree_cons (NULL_TREE, ptr_type_node, parmtypes); /* Build the function type itself. */ fntype = build_function_type (void_type_node, parmtypes); @@ -5468,7 +5470,7 @@ start_cleanup_fn (void) DECL_DECLARED_INLINE_P (fndecl) = 1; DECL_INTERFACE_KNOWN (fndecl) = 1; /* Build the parameter. */ - if (flag_use_cxa_atexit) + if (use_cxa_atexit) { tree parmdecl; @@ -5537,7 +5539,7 @@ register_dtor_fn (tree decl) cxx_mark_addressable (cleanup); mark_used (cleanup); cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); - if (flag_use_cxa_atexit) + if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ()) { args = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0), diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index cc448bcc687..c4dc052ddbe 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8971,6 +8971,14 @@ should be used to register static destructors when @option{-fuse-cxa-atexit} is in effect. The default is to return false to use @code{__cxa_atexit}. @end deftypefn +@deftypefn {Target Hook} bool TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT (void) +This hook returns true if the target @code{atexit} function can be used +in the same manner as @code{__cxa_atexit} to register C++ static +destructors. This requires that @code{atexit}-registered functions in +shared libraries are run in the correct order when the libraries are +unloaded. The default is to return false. +@end deftypefn + @deftypefn {Target Hook} void TARGET_CXX_ADJUST_CLASS_AT_DEFINITION (tree @var{type}) @var{type} is a C++ class (i.e., RECORD_TYPE or UNION_TYPE) that has just been defined. Use this hook to make adjustments to the class (eg, tweak diff --git a/gcc/target-def.h b/gcc/target-def.h index 74cf86583d7..82e711a79c7 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -583,6 +583,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define TARGET_CXX_USE_AEABI_ATEXIT hook_bool_void_false #endif +#ifndef TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT +#define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_false +#endif + #ifndef TARGET_CXX_ADJUST_CLASS_AT_DEFINITION #define TARGET_CXX_ADJUST_CLASS_AT_DEFINITION hook_void_tree #endif @@ -599,6 +603,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY, \ TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT, \ TARGET_CXX_USE_AEABI_ATEXIT, \ + TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT, \ TARGET_CXX_ADJUST_CLASS_AT_DEFINITION \ } diff --git a/gcc/target.h b/gcc/target.h index c18fd62b0e6..b193b624f39 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -776,6 +776,9 @@ struct gcc_target /* Returns true if __aeabi_atexit should be used to register static destructors. */ bool (*use_aeabi_atexit) (void); + /* Returns true if target may use atexit in the same manner as + __cxa_atexit to register static destructors. */ + bool (*use_atexit_for_cxa_atexit) (void); /* TYPE is a C++ class (i.e., RECORD_TYPE or UNION_TYPE) that has just been defined. Use this hook to make adjustments to the class (eg, tweak visibility or perform any other required -- 2.11.0