<pre style='margin:0'>
Chris Jones (cjones051073) pushed a commit to branch master
in repository macports-ports.
</pre>
<p><a href="https://github.com/macports/macports-ports/commit/633013903c3b3c06c8c2aea33aac2319777d0e92">https://github.com/macports/macports-ports/commit/633013903c3b3c06c8c2aea33aac2319777d0e92</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new 633013903c3 gcc11: patch for output failure in gfortran (darwin21)
</span>633013903c3 is described below
<span style='display:block; white-space:pre;color:#808000;'>commit 633013903c3b3c06c8c2aea33aac2319777d0e92
</span>Author: Remko Scharroo <remko.scharroo@eumetsat.int>
AuthorDate: Fri Nov 19 03:05:51 2021 +0100
<span style='display:block; white-space:pre;color:#404040;'> gcc11: patch for output failure in gfortran (darwin21)
</span>---
lang/gcc11/Portfile | 5 +-
lang/gcc11/files/patch-darwin21-fortran.diff | 388 +++++++++++++++++++++++++++
2 files changed, 392 insertions(+), 1 deletion(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/gcc11/Portfile b/lang/gcc11/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index b93f39c739c..c2d85163ee5 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/lang/gcc11/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/gcc11/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -13,7 +13,7 @@ name gcc11
</span>
# Note, ARM builds have their own version below...
version 11.2.0
<span style='display:block; white-space:pre;background:#ffe0e0;'>-revision 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision 2
</span>
platforms darwin
categories lang
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -69,6 +69,9 @@ if { ${os.platform} eq "darwin" } {
</span> # respective version is used by macports.
# See also: https://github.com/iains/gcc-darwin-arm64/commit/20f61faaed3b335d792e38892d826054d2ac9f15
patchfiles-append patch-darwin21-support.diff
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ # This following patch works around a problem on MacOS 12.0 with fortran
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # See also: https://gcc.gnu.org/git/?p=gcc.git;a=patch;h=fabe8cc41e9b01913e2016861237d1d99d7567bf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ patchfiles-append patch-darwin21-fortran.diff
</span> }
if { ${os.platform} eq "darwin" && ${os.major} >= 17 } {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/gcc11/files/patch-darwin21-fortran.diff b/lang/gcc11/files/patch-darwin21-fortran.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..ac783817d4f
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/gcc11/files/patch-darwin21-fortran.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,388 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From fabe8cc41e9b01913e2016861237d1d99d7567bf Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Iain Sandoe <iain@sandoe.co.uk>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Thu, 4 Nov 2021 09:37:14 +0000
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] IPA: Provide a mechanism to register static DTORs via
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cxa_atexit.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+For at least one target (Darwin) the platform convention is to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+register static destructors (i.e. __attribute__((destructor)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+with __cxa_atexit rather than placing them into a list that is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+run by some other mechanism.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This patch provides a target hook that allows a target to opt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+into this and handling for the process in ipa_cdtor_merge ().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+When the mode is enabled (dtors_from_cxa_atexit is set) we:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Generate new CTORs to register static destructors with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ __cxa_atexit and add them to the existing list of CTORs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ we then process the revised CTORs list.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * We sort the DTORs into priority and then TU order, this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ means that they are registered in that order with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ __cxa_atexit () and therefore will be run in the reverse
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ order.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Likewise, CTORs are sorted into priority and then TU order,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ which means that they will run in that order.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This matches the behavior of using init/fini (or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mod_init_func/mod_term_func) sections.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This also fixes a bug where Fortran needs a DTOR to be run to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+close IO.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PR fortran/102992
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+gcc/ChangeLog:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * config/darwin.h (TARGET_DTORS_FROM_CXA_ATEXIT): New.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * doc/tm.texi: Regenerated.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * doc/tm.texi.in: Add TARGET_DTORS_FROM_CXA_ATEXIT hook.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ipa.c (cgraph_build_static_cdtor_1): Return the built
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ function decl.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (build_cxa_atexit_decl): New.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (build_dso_handle_decl): New.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (build_cxa_dtor_registrations): New.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (compare_cdtor_tu_order): New.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (build_cxa_atexit_fns): New.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (ipa_cdtor_merge): If dtors_from_cxa_atexit is set,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ process the DTORs/CTORs accordingly.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (pass_ipa_cdtor_merge::gate): Also run if
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dtors_from_cxa_atexit is set.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * target.def (dtors_from_cxa_atexit): New hook.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gcc/config/darwin.h | 5 ++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gcc/doc/tm.texi | 8 ++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gcc/doc/tm.texi.in | 2 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gcc/ipa.c | 200 +++++++++++++++++++++++++++++++++++++++++++-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gcc/target.def | 10 +++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 5 files changed, 221 insertions(+), 4 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index e54cbb11cee..7ed01efa694 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- gcc/config/darwin.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ gcc/config/darwin.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -54,6 +54,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define DO_GLOBAL_DTORS_BODY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* Register static destructors to run from __cxa_atexit instead of putting
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ them into a .mod_term_funcs section. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define TARGET_DTORS_FROM_CXA_ATEXIT true
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* The string value for __SIZE_TYPE__. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifndef SIZE_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 78a1af1ad4d..6ec1d50b3e4 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- gcc/doc/tm.texi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ gcc/doc/tm.texi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -9210,6 +9210,14 @@ collecting constructors and destructors to be run at startup and exit.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ It is false if we must use @command{collect2}.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @end deftypevr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++@deftypevr {Target Hook} bool TARGET_DTORS_FROM_CXA_ATEXIT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++This value is true if the target wants destructors to be queued to be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++run from __cxa_atexit. If this is the case then, for each priority level,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++a new constructor will be entered that registers the destructors for that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++level with __cxa_atexit (and there will be no destructors emitted).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++It is false the method implied by @code{have_ctors_dtors} is used.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++@end deftypevr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @deftypefn {Target Hook} void TARGET_ASM_CONSTRUCTOR (rtx @var{symbol}, int @var{priority})
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ If defined, a function that outputs assembler code to arrange to call
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ the function referenced by @var{symbol} at initialization time.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 4401550989e..2b9960b73d7 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- gcc/doc/tm.texi.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ gcc/doc/tm.texi.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -6015,6 +6015,8 @@ encountering an @code{init_priority} attribute.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @hook TARGET_HAVE_CTORS_DTORS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++@hook TARGET_DTORS_FROM_CXA_ATEXIT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @hook TARGET_ASM_CONSTRUCTOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ @hook TARGET_ASM_DESTRUCTOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gcc/ipa.c b/gcc/ipa.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 4f62ac183ee..325b658b55e 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- gcc/ipa.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ gcc/ipa.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -837,7 +837,7 @@ ipa_discover_variable_flags (void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ FINAL specify whether the externally visible name for collect2 should
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ be produced. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static tree
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tree optimization,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tree target)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -916,6 +916,7 @@ cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set_cfun (NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ current_function_decl = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return decl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Generate and emit a static constructor or destructor. WHICH must
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1022,6 +1023,124 @@ build_cdtor (bool ctor_p, const vec<tree> &cdtors)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* Helper functions for build_cxa_dtor_registrations ().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Build a decl for __cxa_atexit (). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static tree
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++build_cxa_atexit_decl ()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* The parameter to "__cxa_atexit" is "void (*)(void *)". */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree fn_type = build_function_type_list (void_type_node,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ptr_type_node, NULL_TREE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree fn_ptr_type = build_pointer_type (fn_type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* The declaration for `__cxa_atexit' is:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int __cxa_atexit (void (*)(void *), void *, void *). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const char *name = "__cxa_atexit";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree cxa_name = get_identifier (name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ fn_type = build_function_type_list (integer_type_node, fn_ptr_type,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ptr_type_node, ptr_type_node, NULL_TREE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree atexit_fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cxa_name, fn_type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SET_DECL_ASSEMBLER_NAME (atexit_fndecl, cxa_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_VISIBILITY (atexit_fndecl) = VISIBILITY_DEFAULT;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_VISIBILITY_SPECIFIED (atexit_fndecl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ set_call_expr_flags (atexit_fndecl, ECF_LEAF | ECF_NOTHROW);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TREE_PUBLIC (atexit_fndecl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_EXTERNAL (atexit_fndecl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_ARTIFICIAL (atexit_fndecl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return atexit_fndecl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* Build a decl for __dso_handle. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static tree
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++build_dso_handle_decl ()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Declare the __dso_handle variable. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree dso_handle_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ get_identifier ("__dso_handle"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ptr_type_node);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TREE_PUBLIC (dso_handle_decl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_EXTERNAL (dso_handle_decl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_ARTIFICIAL (dso_handle_decl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_GAS_HIDDEN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (dso_handle_decl != error_mark_node)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_VISIBILITY (dso_handle_decl) = VISIBILITY_HIDDEN;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_VISIBILITY_SPECIFIED (dso_handle_decl) = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return dso_handle_decl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* This builds one or more constructor functions that register DTORs with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ __cxa_atexit (). Within a priority level, DTORs are registered in TU
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ order - which means that they will run in reverse TU order from cxa_atexit.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ This is the same behavior as using a .fini / .mod_term_funcs section.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ As the functions are built, they are appended to the CTORs vector. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++build_cxa_dtor_registrations (const vec<tree> &dtors, vec<tree> *ctors)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ size_t i,j;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ size_t len = dtors.length ();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ location_t sav_loc = input_location;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ input_location = UNKNOWN_LOCATION;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree atexit_fndecl = build_cxa_atexit_decl ();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree dso_handle_decl = build_dso_handle_decl ();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* We want &__dso_handle. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree dso_ptr = build1_loc (UNKNOWN_LOCATION, ADDR_EXPR,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ptr_type_node, dso_handle_decl);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ i = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while (i < len)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority_type priority = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree body = NULL_TREE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ j = i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority_type p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree fn = dtors[j];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ p = DECL_FINI_PRIORITY (fn);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (j == i)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority = p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else if (p != priority)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ j++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while (j < len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Find the next batch of destructors with the same initialization
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (;i < j; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree fn = dtors[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_STATIC_DESTRUCTOR (fn) = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree dtor_ptr = build1_loc (UNKNOWN_LOCATION, ADDR_EXPR,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ptr_type_node, fn);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree call_cxa_atexit
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ = build_call_expr_loc (UNKNOWN_LOCATION, atexit_fndecl, 3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dtor_ptr, null_pointer_node, dso_ptr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TREE_SIDE_EFFECTS (call_cxa_atexit) = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ append_to_statement_list (call_cxa_atexit, &body);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gcc_assert (body != NULL_TREE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Generate a function to register the DTORs at this priority. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree new_ctor
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ = cgraph_build_static_cdtor_1 ('I', body, priority, true,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (dtors[0]),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DECL_FUNCTION_SPECIFIC_TARGET (dtors[0]));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Add this to the list of ctors. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ctors->safe_push (new_ctor);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ input_location = sav_loc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Comparison function for qsort. P1 and P2 are actually of type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "tree *" and point to static constructors. DECL_INIT_PRIORITY is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ used to determine the sort order. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1071,7 +1190,46 @@ compare_dtor (const void *p1, const void *p2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (priority1 > priority2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* Ensure a stable sort. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* Ensure a stable sort - into TU order. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return DECL_UID (f1) - DECL_UID (f2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* Comparison function for qsort. P1 and P2 are of type "tree *" and point to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ a pair of static constructors or destructors. We first sort on the basis of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority and then into TU order (on the strict assumption that DECL_UIDs are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ordered in the same way as the original functions). ???: this seems quite
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ fragile. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++compare_cdtor_tu_order (const void *p1, const void *p2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree f1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tree f2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int priority1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int priority2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ f1 = *(const tree *)p1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ f2 = *(const tree *)p2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* We process the DTORs first, and then remove their flag, so this order
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ allows for functions that are declared as both CTOR and DTOR. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (DECL_STATIC_DESTRUCTOR (f1))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gcc_checking_assert (DECL_STATIC_DESTRUCTOR (f2));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority1 = DECL_FINI_PRIORITY (f1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority2 = DECL_FINI_PRIORITY (f2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority1 = DECL_INIT_PRIORITY (f1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ priority2 = DECL_INIT_PRIORITY (f2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (priority1 < priority2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else if (priority1 > priority2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* For equal priority, sort into the order of definition in the TU. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return DECL_UID (f1) - DECL_UID (f2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1097,6 +1255,37 @@ build_cdtor_fns (vec<tree> *ctors, vec<tree> *dtors)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* Generate new CTORs to register static destructors with __cxa_atexit and add
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ them to the existing list of CTORs; we then process the revised CTORs list.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ We sort the DTORs into priority and then TU order, this means that they are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ registered in that order with __cxa_atexit () and therefore will be run in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ the reverse order.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Likewise, CTORs are sorted into priority and then TU order, which means that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ they will run in that order.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ This matches the behavior of using init/fini or mod_init_func/mod_term_func
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sections. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++build_cxa_atexit_fns (vec<tree> *ctors, vec<tree> *dtors)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!dtors->is_empty ())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gcc_assert (targetm.dtors_from_cxa_atexit);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dtors->qsort (compare_cdtor_tu_order);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ build_cxa_dtor_registrations (*dtors, ctors);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!ctors->is_empty ())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gcc_assert (targetm.dtors_from_cxa_atexit);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ctors->qsort (compare_cdtor_tu_order);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ build_cdtor (/*ctor_p=*/true, *ctors);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Look for constructors and destructors and produce function calling them.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ This is needed for targets not supporting ctors or dtors, but we perform the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ transformation also at linktime to merge possibly numerous
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1115,7 +1304,10 @@ ipa_cdtor_merge (void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (DECL_STATIC_CONSTRUCTOR (node->decl)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ || DECL_STATIC_DESTRUCTOR (node->decl))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ record_cdtor_fn (node, &ctors, &dtors);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- build_cdtor_fns (&ctors, &dtors);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (targetm.dtors_from_cxa_atexit)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ build_cxa_atexit_fns (&ctors, &dtors);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ build_cdtor_fns (&ctors, &dtors);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1162,7 +1354,7 @@ pass_ipa_cdtor_merge::gate (function *)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Perform the pass when we have no ctors/dtors support
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ or at LTO time to merge multiple constructors into single
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ function. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return !targetm.have_ctors_dtors || in_lto_p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return !targetm.have_ctors_dtors || in_lto_p || targetm.dtors_from_cxa_atexit;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } // anon namespace
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gcc/target.def b/gcc/target.def
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 51ea167172b..b803c582f01 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- gcc/target.def
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ gcc/target.def
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -6778,6 +6778,16 @@ collecting constructors and destructors to be run at startup and exit.\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ It is false if we must use @command{collect2}.",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool, false)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* True if the target wants DTORs to be run from cxa_atexit. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DEFHOOKPOD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++(dtors_from_cxa_atexit,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ "This value is true if the target wants destructors to be queued to be\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++run from __cxa_atexit. If this is the case then, for each priority level,\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++a new constructor will be entered that registers the destructors for that\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++level with __cxa_atexit (and there will be no destructors emitted).\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++It is false the method implied by @code{have_ctors_dtors} is used.",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool, false)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* True if thread-local storage is supported. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ DEFHOOKPOD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (have_tls,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+2.27.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span></pre><pre style='margin:0'>
</pre>