https://gcc.gnu.org/g:3002e1f69abbb45a570b66383f5d2ad562190807

commit 3002e1f69abbb45a570b66383f5d2ad562190807
Author: Tobias Burnus <tbur...@baylibre.com>
Date:   Mon Jan 27 12:35:53 2025 +0100

    OpenMP: Add 'interop' clause to 'dispatch' for C/C++
    
    Will fail with an error if/as no suitable 'append_args' has been specified,
    given that 'append_args' is not yet implemented.
    
    gcc/c-family/ChangeLog:
    
            * c-pragma.h (enum pragma_omp_clause): Add 
PRAGMA_OMP_CLAUSE_INTEROP.
    
    gcc/c/ChangeLog:
    
            * c-parser.cc (c_parser_omp_clause_interop): New.
            (c_parser_omp_clause_name, c_parser_omp_all_clauses,
            c_parser_omp_dispatch_body): Handle 'interop' clause.
            * c-typeck.cc (c_finish_omp_clauses): Likewise.
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_omp_clause_name, cp_parser_omp_all_clauses,
            cp_parser_omp_dispatch_body): Handle 'interop' clause.
            * pt.cc (tsubst_omp_clauses): Likewise.
            * semantics.cc (finish_omp_clauses): Likewise.
    
    gcc/ChangeLog:
    
            * gimplify.cc (gimplify_call_expr): Add initial support for
            dispatch's 'interop' clause.
            (gimplify_scan_omp_clauses): Handle interop clause.
            * tree-pretty-print.cc (dump_omp_clause): Likewise.
            * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_INTEROP.
            * tree.cc (omp_clause_num_ops, omp_clause_code_name): Add interop.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/gomp/dispatch-11.c: New test.
            * c-c++-common/gomp/dispatch-12.c: New test.
    
    (cherry picked from commit f34422e06c38eb1f69c301ad5d8e2114c46a2796)

Diff:
---
 gcc/ChangeLog.omp                             | 12 ++++
 gcc/c-family/ChangeLog.omp                    |  7 +++
 gcc/c-family/c-pragma.h                       |  1 +
 gcc/c/ChangeLog.omp                           | 10 ++++
 gcc/c/c-parser.cc                             | 17 ++++++
 gcc/c/c-typeck.cc                             | 23 ++++++--
 gcc/cp/ChangeLog.omp                          | 10 ++++
 gcc/cp/parser.cc                              | 10 ++++
 gcc/cp/pt.cc                                  |  1 +
 gcc/cp/semantics.cc                           | 29 ++++++---
 gcc/gimplify.cc                               | 15 +++++
 gcc/testsuite/ChangeLog.omp                   |  8 +++
 gcc/testsuite/c-c++-common/gomp/dispatch-11.c | 84 +++++++++++++++++++++++++++
 gcc/testsuite/c-c++-common/gomp/dispatch-12.c | 53 +++++++++++++++++
 gcc/tree-core.h                               |  3 +
 gcc/tree-pretty-print.cc                      |  6 +-
 gcc/tree.cc                                   |  2 +
 17 files changed, 275 insertions(+), 16 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index cf11ac6d3242..e83fe6afebb4 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,15 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-11-22  Tobias Burnus  <tbur...@baylibre.com>
+
+       * gimplify.cc (gimplify_call_expr): Add initial support for
+       dispatch's 'interop' clause.
+       (gimplify_scan_omp_clauses): Handle interop clause.
+       * tree-pretty-print.cc (dump_omp_clause): Likewise.
+       * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_INTEROP.
+       * tree.cc (omp_clause_num_ops, omp_clause_code_name): Add interop.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/c-family/ChangeLog.omp b/gcc/c-family/ChangeLog.omp
index 852acb8a2039..cf966f7be0f4 100644
--- a/gcc/c-family/ChangeLog.omp
+++ b/gcc/c-family/ChangeLog.omp
@@ -1,3 +1,10 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-11-22  Tobias Burnus  <tbur...@baylibre.com>
+
+       * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_INTEROP.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index bea0d9121cb2..ef452fc102ca 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -135,6 +135,7 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_INDIRECT,
   PRAGMA_OMP_CLAUSE_INIT,
   PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR,
+  PRAGMA_OMP_CLAUSE_INTEROP,
   PRAGMA_OMP_CLAUSE_LASTPRIVATE,
   PRAGMA_OMP_CLAUSE_LINEAR,
   PRAGMA_OMP_CLAUSE_LINK,
diff --git a/gcc/c/ChangeLog.omp b/gcc/c/ChangeLog.omp
index 4323cd1b239d..a19c27f82634 100644
--- a/gcc/c/ChangeLog.omp
+++ b/gcc/c/ChangeLog.omp
@@ -1,3 +1,13 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-11-22  Tobias Burnus  <tbur...@baylibre.com>
+
+       * c-parser.cc (c_parser_omp_clause_interop): New.
+       (c_parser_omp_clause_name, c_parser_omp_all_clauses,
+       c_parser_omp_dispatch_body): Handle 'interop' clause.
+       * c-typeck.cc (c_finish_omp_clauses): Likewise.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index df369a7090f3..4c1cead30248 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -15158,6 +15158,8 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_INIT;
          else if (!strcmp ("is_device_ptr", p))
            result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
+         else if (!strcmp ("interop", p))
+           result = PRAGMA_OMP_CLAUSE_INTEROP;
          break;
        case 'l':
          if (!strcmp ("lastprivate", p))
@@ -20526,6 +20528,16 @@ c_parser_omp_clause_use (c_parser *parser, tree list)
   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE, list);
 }
 
+/* OpenMP 6.0:
+   interop ( variable-list ) */
+
+static tree
+c_parser_omp_clause_interop (c_parser *parser, tree list)
+{
+  check_no_duplicate_clause (list, OMP_CLAUSE_INTEROP, "interop");
+  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_INTEROP, list);
+}
+
 /* Parse all OpenACC clauses.  The set clauses allowed by the directive
    is a bitmask in MASK.  Return the list of clauses found.  */
 
@@ -21037,6 +21049,10 @@ c_parser_omp_all_clauses (c_parser *parser, 
omp_clause_mask mask,
          clauses = c_parser_omp_clause_use (parser, clauses);
          c_name = "use";
          break;
+       case PRAGMA_OMP_CLAUSE_INTEROP:
+         clauses = c_parser_omp_clause_interop (parser, clauses);
+         c_name = "interop";
+         break;
        case PRAGMA_OMP_CLAUSE_MAP:
          clauses = c_parser_omp_clause_map (parser, clauses, GOMP_MAP_TOFROM);
          c_name = "map";
@@ -25033,6 +25049,7 @@ c_parser_omp_dispatch_body (c_parser *parser)
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)                           
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOVARIANTS)                       
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOCONTEXT)                        
\
+   | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INTEROP)                          
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)                    
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
 
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 018ba344d892..9e444b4f009f 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -16517,16 +16517,27 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
              error_at (OMP_CLAUSE_LOCATION (c),
                        "%qD appears more than once in action clauses", t);
              remove = true;
+             break;
            }
-         else if (/* ort == C_ORT_OMP_INTEROP [uncomment for depobj init]  */
+         bitmap_set_bit (&generic_head, DECL_UID (t));
+         /* FALLTHRU */
+       case OMP_CLAUSE_INTEROP:
+         if (/* ort == C_ORT_OMP_INTEROP [uncomment for depobj init]  */
                   !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
-           error_at (OMP_CLAUSE_LOCATION (c),
-                     "%qD must be of %<omp_interop_t%>", OMP_CLAUSE_DECL (c));
-         else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "%qD must be of %<omp_interop_t%>",
+                       OMP_CLAUSE_DECL (c));
+             remove = true;
+           }
+         else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
+                   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
                   && TREE_READONLY (OMP_CLAUSE_DECL (c)))
-           error_at (OMP_CLAUSE_LOCATION (c),
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
                      "%qD shall not be const", OMP_CLAUSE_DECL (c));
-         bitmap_set_bit (&generic_head, DECL_UID (t));
+             remove = true;
+           }
          pc = &OMP_CLAUSE_CHAIN (c);
          break;
        default:
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index 41d2eb6f157a..feb5fbb0b09d 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,3 +1,13 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-11-22  Tobias Burnus  <tbur...@baylibre.com>
+
+       * parser.cc (cp_parser_omp_clause_name, cp_parser_omp_all_clauses,
+       cp_parser_omp_dispatch_body): Handle 'interop' clause.
+       * pt.cc (tsubst_omp_clauses): Likewise.
+       * semantics.cc (finish_omp_clauses): Likewise.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e23aaf1c5a12..7d65fc2fa674 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -38127,6 +38127,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_INDIRECT;
          else if (!strcmp ("init", p))
            result = PRAGMA_OMP_CLAUSE_INIT;
+         else if (!strcmp ("interop", p))
+           result = PRAGMA_OMP_CLAUSE_INTEROP;
          else if (!strcmp ("is_device_ptr", p))
            result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
          break;
@@ -43724,6 +43726,13 @@ cp_parser_omp_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
          clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE, clauses);
          c_name = "use";
          break;
+       case PRAGMA_OMP_CLAUSE_INTEROP:
+         check_no_duplicate_clause (clauses, OMP_CLAUSE_INTEROP, "interop",
+                                    token->location);
+         clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_INTEROP,
+                                           clauses);
+         c_name = "interop";
+         break;
        case PRAGMA_OMP_CLAUSE_DETACH:
          clauses = cp_parser_omp_clause_detach (parser, clauses);
          c_name = "detach";
@@ -50182,6 +50191,7 @@ cp_parser_omp_dispatch_body (cp_parser *parser)
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)                           
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOVARIANTS)                       
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOCONTEXT)                        
\
+   | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INTEROP)                          
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)                    
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 5c9aff0f1c1d..2dcdebcc0219 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -17863,6 +17863,7 @@ tsubst_omp_clauses (tree clauses, enum 
c_omp_region_type ort,
          /* FALLTHRU */
        case OMP_CLAUSE_DESTROY:
        case OMP_CLAUSE_USE:
+       case OMP_CLAUSE_INTEROP:
          OMP_CLAUSE_OPERAND (nc, 0)
            = tsubst_stmt (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl);
          break;
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 600f90ba4c4b..f0a6d464538f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -9730,20 +9730,31 @@ finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
              error_at (OMP_CLAUSE_LOCATION (c),
                        "%qD appears more than once in action clauses", t);
              remove = true;
+             break;
            }
+         bitmap_set_bit (&generic_head, DECL_UID (t));
+         /* FALLTHRU */
+       case OMP_CLAUSE_INTEROP:
          if (!processing_template_decl)
            {
-             if (/* ort == C_ORT_OMP_INTEROP [uncomment for depobj init]  */
-                  !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
-               error_at (OMP_CLAUSE_LOCATION (c),
-                         "%qD must be of %<omp_interop_t%>",
-                         OMP_CLAUSE_DECL (c));
-             else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE
+             if (/* (ort == C_ORT_OMP_INTEROP [uncomment for depobj init]
+                     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP) &&  */
+                 !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "%qD must be of %<omp_interop_t%>",
+                           OMP_CLAUSE_DECL (c));
+                 remove = true;
+               }
+             else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
+                       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
                       && TREE_READONLY (OMP_CLAUSE_DECL (c)))
-               error_at (OMP_CLAUSE_LOCATION (c),
-                         "%qD shall not be const", OMP_CLAUSE_DECL (c));
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "%qD shall not be const", OMP_CLAUSE_DECL (c));
+                 remove = true;
+               }
            }
-         bitmap_set_bit (&generic_head, DECL_UID (t));
          pc = &OMP_CLAUSE_CHAIN (c);
          break;
        default:
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 99b227e41f26..cd9bb8d701e1 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -4341,6 +4341,20 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
      vars there.  */
   bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
 
+  tree dispatch_interop = NULL_TREE;
+  if (flag_openmp
+      && gimplify_omp_ctxp != NULL
+      && gimplify_omp_ctxp->code == OMP_DISPATCH
+      && gimplify_omp_ctxp->clauses
+      && (dispatch_interop = omp_find_clause (gimplify_omp_ctxp->clauses,
+                                             OMP_CLAUSE_INTEROP)) != NULL_TREE)
+    /* FIXME: When implementing 'append_args, use the 'device_num' of
+       the argument.  */
+    error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
+             "number of list items in %<interop%> clause exceeds number of "
+             "%<append_args%> items for %<declare variant%> candidate %qD",
+             fndecl);
+
   /* Gimplify the function arguments.  */
   if (nargs > 0)
     {
@@ -14133,6 +14147,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
        case OMP_CLAUSE_BIND:
        case OMP_CLAUSE_IF_PRESENT:
        case OMP_CLAUSE_FINALIZE:
+       case OMP_CLAUSE_INTEROP:
          break;
 
        case OMP_CLAUSE__OMPACC_:
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index f5b97f749c7d..bd3d806ad08a 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,11 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-11-22  Tobias Burnus  <tbur...@baylibre.com>
+
+       * c-c++-common/gomp/dispatch-11.c: New test.
+       * c-c++-common/gomp/dispatch-12.c: New test.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-11.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-11.c
new file mode 100644
index 000000000000..7f1d8062f25c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-11.c
@@ -0,0 +1,84 @@
+/* { dg-additional-options "-fdump-tree-original"  }  */
+
+/* The following definitions are in omp_lib, which cannot be included
+   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;
+
+
+float repl1();
+#pragma omp declare variant(repl1) match(construct={dispatch})
+float base1();
+
+void repl2(int *, int *);
+#pragma omp declare variant(repl2) match(construct={dispatch}) 
adjust_args(need_device_ptr : y)
+void base2(int *x, int *y);
+
+
+float
+dupl (int *a, int *b)
+{
+  omp_interop_t obj1, obj2;
+  float x;
+
+  #pragma omp dispatch interop ( obj1 ) interop(obj2)  /* { dg-error "too many 
'interop' clauses" }  */
+    x = base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch interop ( obj1) nocontext(1) interop (obj2 )  /* { 
dg-error "too many 'interop' clauses" }  */
+    base2 (a, b);
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'base2'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void base2\\(int\\*, 
int\\*\\)'" "" { target c++ } .-3 } */
+  return x;
+}
+
+
+float
+test (int *a, int *b)
+{
+  omp_interop_t obj1, obj2;
+  float x, y;
+
+  #pragma omp dispatch interop ( obj1 )
+    x = base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch interop ( obj1, obj1 )  /* Twice the same - should be 
fine.  */
+    x = base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch novariants(1) interop(obj2, obj1)
+    y = base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'base1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'float base1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch interop(obj2, obj1)
+    base2 (a, b);
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl2'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void repl2\\(int\\*, 
int\\*\\)'" "" { target c++ } .-3 } */
+
+  #pragma omp dispatch interop(obj2) nocontext(1)
+    base2 (a, b);
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'base2'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void base2\\(int\\*, 
int\\*\\)'" "" { target c++ } .-3 } */
+  return x + y;
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch 
interop\\(obj1\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) 
interop\\(obj1\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) 
interop\\(obj2\\) novariants\\(1\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) 
interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch nocontext\\(1\\) 
interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-12.c 
b/gcc/testsuite/c-c++-common/gomp/dispatch-12.c
new file mode 100644
index 000000000000..ea190c74e84f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-12.c
@@ -0,0 +1,53 @@
+/* The following definitions are in omp_lib, which cannot be included
+   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;
+
+
+void repl1();
+#pragma omp declare variant(repl1) match(construct={dispatch})
+void base1();
+
+void
+test ()
+{
+  const omp_interop_t obj1 = omp_interop_none;
+  omp_interop_t obj2[2];
+  const omp_interop_t *obj3;
+  short x;
+
+  #pragma omp dispatch interop ( obj1, obj2, obj1 )  /* { dg-error "'obj2' 
must be of 'omp_interop_t'" }  */
+    base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch interop ( obj3 )  /* { dg-error "'obj3' must be of 
'omp_interop_t'" }  */
+    base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch interop ( obj1 )
+    base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch interop ( obj2 )  /* { dg-error "'obj2' must be of 
'omp_interop_t'" }  */
+    base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { 
target c++ } .-3 } */
+
+  #pragma omp dispatch interop ( x )  /* { dg-error "'x' must be of 
'omp_interop_t'" }  */
+    base1 ();
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } 
.-2 } */
+  /* { dg-error "number of list items in 'interop' clause exceeds number of 
'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { 
target c++ } .-3 } */
+}
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index e94f0d2896bd..a9e26ada1077 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -393,6 +393,9 @@ enum omp_clause_code {
   /* OpenMP clause: use (variable-list ).  */
   OMP_CLAUSE_USE,
 
+  /* OpenMP clause: interop (variable-list).  */
+  OMP_CLAUSE_INTEROP,
+
   /* OpenACC clause: gang [(gang-argument-list)].
      Where
       gang-argument-list: [gang-argument-list, ] gang-argument
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 3bb684609ba7..4535b924edae 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -1680,7 +1680,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int 
spc, dump_flags_t flags)
                         spc, flags, false);
       pp_right_paren (pp);
       break;
-
+    case OMP_CLAUSE_INTEROP:
+      pp_string (pp, "interop(");
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false);
+      pp_right_paren (pp);
+      break;
     case OMP_CLAUSE_IF_PRESENT:
       pp_string (pp, "if_present");
       break;
diff --git a/gcc/tree.cc b/gcc/tree.cc
index fae1e920e9c2..445ed7520550 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -274,6 +274,7 @@ unsigned const char omp_clause_num_ops[] =
   1, /* OMP_CLAUSE_DESTROY  */
   2, /* OMP_CLAUSE_INIT  */
   1, /* OMP_CLAUSE_USE  */
+  1, /* OMP_CLAUSE_INTEROP  */
   2, /* OMP_CLAUSE_GANG  */
   1, /* OMP_CLAUSE_ASYNC  */
   1, /* OMP_CLAUSE_WAIT  */
@@ -378,6 +379,7 @@ const char * const omp_clause_code_name[] =
   "destroy",
   "init",
   "use",
+  "interop",
   "gang",
   "async",
   "wait",

Reply via email to