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

commit d3998fce2d0bacc3b6390dbf8931558b6e1294c4
Author: Tobias Burnus <tbur...@baylibre.com>
Date:   Thu Mar 27 14:09:20 2025 +0100

    OpenMP: Fix C++ template handling with append_args' prefer_type modifier
    
    It is possible but not very sensible to use C++ templates with in the
    prefer_type modifier to the 'append_args' clause of 'declare variant'.
    
    The commit r15-6336-g12dd892b1a3ad7 added substitution support in pt.cc,
    but missed to update afterward the actual data in decl.cc.
    As gimplification support was only added in r15-8898-gf016ee89955ab4,
    this could not be tested back then. The latter commit added a sorry
    for it gimplify.cc and the existing testcase, which this commit now removes.
    
    gcc/cp/ChangeLog:
    
            * cp-tree.h (cp_finish_omp_init_prefer_type): Add.
            * decl.cc (omp_declare_variant_finalize_one): Call it.
            * pt.cc (tsubst_attribute): Minor rebustification for OpenMP
            append_args handling.
            * semantics.cc (cp_omp_init_prefer_type_update): Rename to ...
            (cp_finish_omp_init_prefer_type): ... this; remove static attribute
            and return modified tree. Move clause handling to ...
            (finish_omp_clauses): ... the caller.
    
    gcc/ChangeLog:
    
            * gimplify.cc (modify_call_for_omp_dispatch): Remove sorry.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/gomp/append-args-1.C: Remove expected dg-sorry.
            * g++.dg/gomp/append-args-8.C: New test.
    
    (cherry picked from commit 7e286b56545e1bd28098cc197e674d02f3849ec3)

Diff:
---
 gcc/ChangeLog.omp                         |  7 +++
 gcc/cp/ChangeLog.omp                      | 14 +++++
 gcc/cp/cp-tree.h                          |  1 +
 gcc/cp/decl.cc                            |  3 +
 gcc/cp/pt.cc                              |  9 ++-
 gcc/cp/semantics.cc                       | 21 +++----
 gcc/gimplify.cc                           |  7 ---
 gcc/testsuite/ChangeLog.omp               |  8 +++
 gcc/testsuite/g++.dg/gomp/append-args-1.C |  4 +-
 gcc/testsuite/g++.dg/gomp/append-args-8.C | 93 +++++++++++++++++++++++++++++++
 10 files changed, 146 insertions(+), 21 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 7643b4610125..3e349ac21873 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,10 @@
+2025-03-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2025-03-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       * gimplify.cc (modify_call_for_omp_dispatch): Remove sorry.
+
 2025-03-27  Thomas Schwinge  <tschwi...@baylibre.com>
 
        Backported from trunk:
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index d581e233f71d..a19bcfa94fdd 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,3 +1,17 @@
+2025-03-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2025-03-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       * cp-tree.h (cp_finish_omp_init_prefer_type): Add.
+       * decl.cc (omp_declare_variant_finalize_one): Call it.
+       * pt.cc (tsubst_attribute): Minor rebustification for OpenMP
+       append_args handling.
+       * semantics.cc (cp_omp_init_prefer_type_update): Rename to ...
+       (cp_finish_omp_init_prefer_type): ... this; remove static attribute
+       and return modified tree. Move clause handling to ...
+       (finish_omp_clauses): ... the caller.
+
 2025-03-27  Thomas Schwinge  <tschwi...@baylibre.com>
 
        Backported from trunk:
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8eade3a3beaa..8047be09b55f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7920,6 +7920,7 @@ extern tree cp_remove_omp_priv_cleanup_stmt       (tree 
*, int *, void *);
 extern bool cp_check_omp_declare_reduction     (tree);
 extern bool cp_check_omp_declare_mapper                (tree);
 extern void finish_omp_declare_simd_methods    (tree);
+extern tree cp_finish_omp_init_prefer_type     (tree);
 extern tree finish_omp_clauses                 (tree, enum c_omp_region_type);
 extern tree omp_instantiate_mappers            (tree);
 extern tree push_omp_privatization_clauses     (bool);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index ff027ead6731..e3ed0d5c9a4d 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -8477,6 +8477,9 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
                    = build_int_cst (TREE_TYPE (nargs),
                                     tree_to_uhwi (TREE_PURPOSE (nargs)) + 1);
                }
+             for (tree t = append_args_list; t; t = TREE_CHAIN (t))
+               TREE_VALUE (t)
+                 = cp_finish_omp_init_prefer_type (TREE_VALUE (t));
              DECL_ATTRIBUTES (variant) = tree_cons (
                get_identifier ("omp declare variant variant args"),
                TREE_VALUE (adjust_args_list), DECL_ATTRIBUTES (variant));
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 45edf8d03971..be7f9ee591c7 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -12003,13 +12003,18 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
       location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain));
       tree ctx = copy_list (TREE_VALUE (val));
       tree append_args_list = TREE_CHAIN (TREE_CHAIN (chain));
-      if (append_args_list && TREE_VALUE (append_args_list))
+      if (append_args_list
+         && TREE_VALUE (append_args_list)
+         && TREE_CHAIN (TREE_VALUE (append_args_list)))
        {
-         append_args_list = TREE_VALUE (TREE_VALUE (append_args_list));
+         append_args_list = TREE_VALUE (append_args_list);
+         append_args_list = TREE_VALUE (TREE_CHAIN (append_args_list));
          for (; append_args_list;
               append_args_list = TREE_CHAIN (append_args_list))
             {
              tree pref_list = TREE_VALUE (append_args_list);
+             if (pref_list == NULL_TREE || TREE_CODE (pref_list) != TREE_LIST)
+               continue;
              tree fr_list = TREE_VALUE (pref_list);
              int len = TREE_VEC_LENGTH (fr_list);
              for (int i = 0; i < len; i++)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index c66f4c79b22f..b5c8a5f4588e 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -7466,17 +7466,17 @@ cp_oacc_check_attachments (tree c)
 /* Update OMP_CLAUSE_INIT_PREFER_TYPE in case template substitution
    happened.  */
 
-static void
-cp_omp_init_prefer_type_update (tree c)
+tree
+cp_finish_omp_init_prefer_type (tree pref_type)
 {
   if (processing_template_decl
-      || OMP_CLAUSE_INIT_PREFER_TYPE (c) == NULL_TREE
-      || TREE_CODE (OMP_CLAUSE_INIT_PREFER_TYPE (c)) != TREE_LIST)
-    return;
+      || pref_type == NULL_TREE
+      || TREE_CODE (pref_type) != TREE_LIST)
+    return pref_type;
 
-  tree t = TREE_PURPOSE (OMP_CLAUSE_INIT_PREFER_TYPE (c));
+  tree t = TREE_PURPOSE (pref_type);
   char *str = const_cast<char *> (TREE_STRING_POINTER (t));
-  tree fr_list = TREE_VALUE (OMP_CLAUSE_INIT_PREFER_TYPE (c));
+  tree fr_list = TREE_VALUE (pref_type);
   int len = TREE_VEC_LENGTH (fr_list);
   int cnt = 0;
 
@@ -7502,7 +7502,7 @@ cp_omp_init_prefer_type_update (tree c)
                  || !tree_fits_shwi_p (value))
                error_at (loc,
                          "expected string literal or "
-                         "constant integer expression instead of %qE", value); 
// FIXME of 'qE' and no 'loc'?
+                         "constant integer expression instead of %qE", value);
              else
                {
                  HOST_WIDE_INT n = tree_to_shwi (value);
@@ -7531,7 +7531,7 @@ cp_omp_init_prefer_type_update (tree c)
       if (cnt >= len)
        break;
     }
-  OMP_CLAUSE_INIT_PREFER_TYPE (c) = t;
+  return t;
 }
 
 /* For all elements of CLAUSES, validate them vs OpenMP constraints.
@@ -9801,7 +9801,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type 
ort)
          break;
        case OMP_CLAUSE_INIT:
          init_seen = true;
-         cp_omp_init_prefer_type_update (c);
+         OMP_CLAUSE_INIT_PREFER_TYPE (c)
+           = cp_finish_omp_init_prefer_type (OMP_CLAUSE_INIT_PREFER_TYPE (c));
          if (!OMP_CLAUSE_INIT_TARGETSYNC (c))
            init_no_targetsync_clause = c;
          /* FALLTHRU */
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 9592b5f8043d..49ff5ace9bcf 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -4093,13 +4093,6 @@ modify_call_for_omp_dispatch (tree expr, tree 
dispatch_clauses,
                  tree pref = TREE_VALUE (a);
                  if (pref == NULL_TREE)
                    pref = null_pointer_node;
-                 else if (TREE_CODE (pref) == TREE_LIST)
-                   {
-                     /* FIXME: this is a bug in the C++ front end.  */
-                     sorry_at (OMP_CLAUSE_LOCATION (dispatch_interop),
-                               "%<prefer_type%> with template function");
-                     pref = null_pointer_node;
-                   }
                  else
                    pref = build_fold_addr_expr (pref);
                  init = build4 (ARRAY_REF, prefer_type_type, prefer_type,
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 2437f76e7553..675f1ba3792d 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,11 @@
+2025-03-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2025-03-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       * g++.dg/gomp/append-args-1.C: Remove expected dg-sorry.
+       * g++.dg/gomp/append-args-8.C: New test.
+
 2025-03-25  Thomas Schwinge  <tschwi...@baylibre.com>
 
        Backported from trunk:
diff --git a/gcc/testsuite/g++.dg/gomp/append-args-1.C 
b/gcc/testsuite/g++.dg/gomp/append-args-1.C
index 6e795869ec1c..dd52fb90fc1c 100644
--- a/gcc/testsuite/g++.dg/gomp/append-args-1.C
+++ b/gcc/testsuite/g++.dg/gomp/append-args-1.C
@@ -97,10 +97,10 @@ test (int *a, int *b)
   #pragma omp dispatch
     base99 ();
 
-  #pragma omp dispatch interop ( obj1 )  // { dg-message "sorry" }
+  #pragma omp dispatch interop ( obj1 )
     base2<int *, omp_interop_t> (b, omp_interop_none);
 
-  #pragma omp dispatch interop ( obj1 )  // { dg-message "sorry" }
+  #pragma omp dispatch interop ( obj1 )
     base2<int *, int *> (b, a);
 
   #pragma omp dispatch interop ( obj1 )
diff --git a/gcc/testsuite/g++.dg/gomp/append-args-8.C 
b/gcc/testsuite/g++.dg/gomp/append-args-8.C
new file mode 100644
index 000000000000..7fbbfa88b886
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/append-args-8.C
@@ -0,0 +1,93 @@
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+/* The following definitions are in omp_lib, which cannot be included
+gcc/testsuite/g++.dg/gomp/append-args-1.C   in gcc/testsuite/  */
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
+{
+  omp_interop_none = 0,
+  __omp_interop_t_max__ = __UINTPTR_MAX__
+} omp_interop_t;
+
+
+template<typename T, typename T2, typename T3>
+void repl2(T, T2, T3, T3);
+#pragma omp declare variant(repl2) match(construct={dispatch}) 
adjust_args(need_device_ptr : y) \
+        append_args(interop(target, targetsync, prefer_type(1)), \
+                    interop(prefer_type({fr(3), 
attr("ompx_nop")},{fr(2)},{attr("ompx_all")})))
+template<typename T, typename T2>
+void base2(T x, T2 y);
+
+
+
+template<typename T, typename T2>
+void repl3(T, T2, T2, T2, ...);
+#pragma omp declare variant(repl3) match(construct={dispatch}) \
+        append_args( interop(target, prefer_type("cuda", "hsa")), \
+                     interop(targetsync), \
+                     interop(prefer_type({attr("ompx_nop")})) )
+template<typename T>
+void base3(T, ...);
+
+
+
+
+float
+test (int *a, int *b)
+{
+  omp_interop_t obj1, obj2;
+  float x, y;
+
+  #pragma omp dispatch interop ( obj1 )
+    base2<int *, int *> (b, a);
+
+  #pragma omp dispatch nocontext(1)
+    base3<int*>(a, 1, 2, "abc");
+
+  #pragma omp dispatch
+    base3<int*>(a, 1, 2, "abc");
+
+  return x;
+}
+
+/* { dg-final { scan-tree-dump-times "base3<int\\*> \\(a, 1, 2, \"abc\"\\);" 1 
"gimple" } }  */
+
+/* { dg-final { scan-tree-dump-times "unsigned.* \\* 
interopobjs.\[0-9\]+\\\[1\\\];" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "unsigned.* \\* 
interopobjs.\[0-9\]+\\\[3\\\];" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "int tgt_tgtsync.\[0-9\]+\\\[1\\\];" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "int tgt_tgtsync.\[0-9\]+\\\[3\\\];" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "const char \\* 
pref_type.\[0-9\]+\\\[1\\\];" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "const char \\* 
pref_type.\[0-9\]+\\\[3\\\];" 1 "gimple" } }  */
+
+/* { dg-final { scan-tree-dump-times "interopobjs.\[0-9\]+\\\[0\\\] = 
&interop\\.\[0-9\]+;" 2 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "interopobjs.\[0-9\]+\\\[1\\\] = 
&interop\\.\[0-9\]+;" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "interopobjs.\[0-9\]+\\\[2\\\] = 
&interop\\.\[0-9\]+;" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[0\\\] = 0;" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[0\\\] = 1;" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[1\\\] = 2;" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[2\\\] = 0;" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[0\\\] = 
\"\\\\x80\\\\x03\\\\x80ompx_nop\\\\x00\\\\x00\\\\x80\\\\x02\\\\x80\\\\x00\\\\x80\\\\x80ompx_all\\\\x00\\\\x00\";"
 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[0\\\] = 
\"\\\\x80\\\\x01\\\\x80\\\\x00\\\\x80\\\\x07\\\\x80\\\\x00\";" 1 "gimple" } }  
*/
+/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[1\\\] = 0B;" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[2\\\] = 
\"\\\\x80\\\\x80ompx_nop\\\\x00\\\\x00\";" 1 "gimple" } }  */
+
+
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = 
__builtin_omp_get_interop_int \\(obj1, -5, 0B\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = 
__builtin_omp_get_default_device \\(\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device 
\\(D\.\[0-9\]+\\);" 2 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = 
__builtin_omp_get_mapped_ptr \\(a, D\.\[0-9\]+\\);" 1 "gimple" } }  */
+
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 
1, interopobjs\.\[0-9\], tgt_tgtsync\.\[0-9\]+, pref_type.2, 0, 0B, 0, 0B, 0, 
0B\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "repl2<int\\*, int\\*, omp_interop_t> 
\\(b, D\.\[0-9\]+, obj1, interop\.\[0-9\]+\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 
0, 0B, 0B, 0B, 0, 0B, 1, interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } }  */
+
+
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 
0B, 0, 0B, 3, interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "repl3<int\\*, omp_interop_t> \\(a, 
interop\.\[0-9\]+3, interop\.\[0-9\]+2, interop\.\[0-9\]+, 1, 2, \"abc\"\\);" 1 
"gimple" } }  */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 3, 
interopobjs\.\[0-9\]+, tgt_tgtsync\.\[0-9\]+, pref_type\.\[0-9\]+, 0, 0B, 0, 
0B, 0, 0B\\);" 1 "gimple" } }  */

Reply via email to