https://gcc.gnu.org/g:caacc841ee735e094e3e7c3b8b067a969006b4df

commit caacc841ee735e094e3e7c3b8b067a969006b4df
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Feb 25 09:29:39 2025 +0100

    openmp: Fix handling of declare target statics with array type which need 
destruction [PR118876]
    
    The following testcase ICEs because it attempts to emit the __tcfa function 
twice,
    once when handling the host destruction and once when handling nohost 
destruction.
    
    This patch fixes it by using __omp_tcfa function for the nohost case and 
marks it
    with the needed "omp declare target" and "omp declare target nohost" 
attributes.
    
    2025-02-25  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/118876
            * cp-tree.h (register_dtor_fn): Add a bool argument defaulted to 
false.
            * decl.cc (start_cleanup_fn): Add OMP_TARGET argument, use
            "__omp_tcf" prefix rather than "__tcf" in that case.  Add
            "omp declare target" and "omp declare target nohost" attributes
            to the fndecl.
            (register_dtor_fn): Add OMP_TARGET argument, pass it down to
            start_cleanup_fn.
            * decl2.cc (one_static_initialization_or_destruction): Add 
OMP_TARGET
            argument, pass it down to register_dtor_fn.
            (emit_partial_init_fini_fn): Pass omp_target to
            one_static_initialization_or_destruction.
            (handle_tls_init): Pass false to
            one_static_initialization_or_destruction.
    
            * g++.dg/gomp/pr118876.C: New test.
    
    (cherry picked from commit 86a4af2793393e47af6b78cb7094c97914890091)

Diff:
---
 gcc/cp/ChangeLog.omp                 | 18 ++++++++++++++++++
 gcc/cp/cp-tree.h                     |  2 +-
 gcc/cp/decl.cc                       | 20 +++++++++++++++-----
 gcc/cp/decl2.cc                      | 12 +++++++-----
 gcc/testsuite/ChangeLog.omp          |  8 ++++++++
 gcc/testsuite/g++.dg/gomp/pr118876.C |  6 ++++++
 6 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index feb6eab350b3..659c56a282ad 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,5 +1,23 @@
 2025-04-25  Thomas Schwinge  <tschwi...@baylibre.com>
 
+       Backported from trunk:
+       2025-02-25  Jakub Jelinek  <ja...@redhat.com>
+
+       PR c++/118876
+       * cp-tree.h (register_dtor_fn): Add a bool argument defaulted to false.
+       * decl.cc (start_cleanup_fn): Add OMP_TARGET argument, use
+       "__omp_tcf" prefix rather than "__tcf" in that case.  Add
+       "omp declare target" and "omp declare target nohost" attributes
+       to the fndecl.
+       (register_dtor_fn): Add OMP_TARGET argument, pass it down to
+       start_cleanup_fn.
+       * decl2.cc (one_static_initialization_or_destruction): Add OMP_TARGET
+       argument, pass it down to register_dtor_fn.
+       (emit_partial_init_fini_fn): Pass omp_target to
+       one_static_initialization_or_destruction.
+       (handle_tls_init): Pass false to
+       one_static_initialization_or_destruction.
+
        Backported from trunk:
        2024-08-07  Julian Brown  <jul...@codesourcery.com>
                    Tobias Burnus  <tob...@baylibre.com>
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 37f4ecb08296..386698cc40e1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7089,7 +7089,7 @@ extern int wrapup_namespace_globals               ();
 extern tree create_implicit_typedef            (tree, tree);
 extern int local_variable_p                    (const_tree);
 extern tree get_cxa_atexit_fn_ptr_type         ();
-extern tree register_dtor_fn                   (tree);
+extern tree register_dtor_fn                   (tree, bool = false);
 extern tmpl_spec_kind current_tmpl_spec_kind   (int);
 extern tree cxx_builtin_function               (tree decl);
 extern tree cxx_builtin_function_ext_scope     (tree decl);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index e3ed0d5c9a4d..b91c88805945 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -93,7 +93,7 @@ static void record_key_method_defined (tree);
 static tree create_array_type_for_decl (tree, tree, tree, location_t);
 static tree get_atexit_node (void);
 static tree get_dso_handle_node (void);
-static tree start_cleanup_fn (bool);
+static tree start_cleanup_fn (bool, bool);
 static void end_cleanup_fn (void);
 static tree cp_make_fname_decl (location_t, tree, int);
 static void initialize_predefined_identifiers (void);
@@ -10004,7 +10004,7 @@ get_dso_handle_node (void)
 static GTY(()) int start_cleanup_cnt;
 
 static tree
-start_cleanup_fn (bool ob_parm)
+start_cleanup_fn (bool ob_parm, bool omp_target)
 {
   char name[32];
 
@@ -10014,7 +10014,8 @@ start_cleanup_fn (bool ob_parm)
   push_lang_context (lang_name_c);
 
   /* Build the name of the function.  */
-  sprintf (name, "__tcf_%d", start_cleanup_cnt++);
+  sprintf (name, "%s_%d",
+          (omp_target ? "__omp_tcf" : "__tcf"), start_cleanup_cnt++);
   tree fntype = TREE_TYPE (ob_parm ? get_cxa_atexit_fn_ptr_type ()
                                   : get_atexit_fn_ptr_type ());
   /* Build the function declaration.  */
@@ -10040,6 +10041,15 @@ start_cleanup_fn (bool ob_parm)
     }
 
   fndecl = pushdecl (fndecl, /*hidden=*/true);
+  if (omp_target)
+    {
+      DECL_ATTRIBUTES (fndecl)
+       = tree_cons (get_identifier ("omp declare target"), NULL_TREE,
+                    DECL_ATTRIBUTES (fndecl));
+      DECL_ATTRIBUTES (fndecl)
+       = tree_cons (get_identifier ("omp declare target nohost"), NULL_TREE,
+                    DECL_ATTRIBUTES (fndecl));
+    }
   start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
 
   pop_lang_context ();
@@ -10061,7 +10071,7 @@ end_cleanup_fn (void)
    static storage duration.  */
 
 tree
-register_dtor_fn (tree decl)
+register_dtor_fn (tree decl, bool omp_target)
 {
   tree cleanup;
   tree addr;
@@ -10107,7 +10117,7 @@ register_dtor_fn (tree decl)
       build_cleanup (decl);
   
       /* Now start the function.  */
-      cleanup = start_cleanup_fn (ob_parm);
+      cleanup = start_cleanup_fn (ob_parm, omp_target);
 
       /* Now, recompute the cleanup.  It may contain SAVE_EXPRs that refer
         to the original function, rather than the anonymous one.  That
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index c534d13a058c..b1754fb8f6c2 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -63,7 +63,7 @@ static tree start_partial_init_fini_fn (bool, unsigned, 
unsigned, bool);
 static void finish_partial_init_fini_fn (tree);
 static tree emit_partial_init_fini_fn (bool, unsigned, tree,
                                       unsigned, location_t, tree);
-static void one_static_initialization_or_destruction (bool, tree, tree);
+static void one_static_initialization_or_destruction (bool, tree, tree, bool);
 static void generate_ctor_or_dtor_function (bool, unsigned, tree, location_t,
                                            bool);
 static tree prune_vars_needing_no_initialization (tree *);
@@ -4276,7 +4276,8 @@ fix_temporary_vars_context_r (tree *node,
    are destroying it.  */
 
 static void
-one_static_initialization_or_destruction (bool initp, tree decl, tree init)
+one_static_initialization_or_destruction (bool initp, tree decl, tree init,
+                                         bool omp_target)
 {
   /* If we are supposed to destruct and there's a trivial destructor,
      nothing has to be done.  */
@@ -4379,7 +4380,7 @@ one_static_initialization_or_destruction (bool initp, 
tree decl, tree init)
       /* If we're using __cxa_atexit, register a function that calls the
         destructor for the object.  */
       if (flag_use_cxa_atexit)
-       finish_expr_stmt (register_dtor_fn (decl));
+       finish_expr_stmt (register_dtor_fn (decl, omp_target));
     }
   else
     finish_expr_stmt (build_cleanup (decl));
@@ -4453,7 +4454,7 @@ emit_partial_init_fini_fn (bool initp, unsigned priority, 
tree vars,
          walk_tree (&init, copy_tree_body_r, &id, NULL);
        }
       /* Do one initialization or destruction.  */
-      one_static_initialization_or_destruction (initp, decl, init);
+      one_static_initialization_or_destruction (initp, decl, init, omp_target);
     }
 
   if (omp_target)
@@ -4961,7 +4962,8 @@ handle_tls_init (void)
     {
       tree var = TREE_VALUE (vars);
       tree init = TREE_PURPOSE (vars);
-      one_static_initialization_or_destruction (/*initp=*/true, var, init);
+      one_static_initialization_or_destruction (/*initp=*/true, var, init,
+                                               false);
 
       /* Output init aliases even with -fno-extern-tls-init.  */
       if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var))
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index d29ae6c0f1f8..d13b5d1f4287 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,11 @@
+2025-04-25  Thomas Schwinge  <tschwi...@baylibre.com>
+
+       Backported from trunk:
+       2025-02-25  Jakub Jelinek  <ja...@redhat.com>
+
+       PR c++/118876
+       * g++.dg/gomp/pr118876.C: New test.
+
 2025-04-17  Kwok Cheung Yeung  <kcye...@baylibre.com>
 
        * c-c++-common/gomp/target-map-iterators-3.c: Update expected Gimple
diff --git a/gcc/testsuite/g++.dg/gomp/pr118876.C 
b/gcc/testsuite/g++.dg/gomp/pr118876.C
new file mode 100644
index 000000000000..242a396bbb63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr118876.C
@@ -0,0 +1,6 @@
+// PR c++/118876
+// { dg-do compile }
+
+#pragma omp declare target
+struct A { ~A () {} } a[2];
+#pragma omp end declare target

Reply via email to