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