<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>