This patch depends on 'dispatch' (which is currently in mainline only
available for C/C++ but not Fortran) and it depends on the not-yet-committed
"[Patch] OpenMP: 'interop' construct - add C/C++ parser support, improve Fortran 
parsing"
https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668782.html
due to be committed soonish.

The idea of the 'interop' clause is to use it with declare_variant + 
'adjust_args',
which is not yet in.  There must be at least as many adjust_args arguments as
'interop' items (restriction). As the former is currently always 0, an error is
be issued unconditionally, making the current implementation fully correct, even
if it is not yet very useful.

The intent is to commit it as follow up very soon after the
'interop' C/C++ parser patch is in.

Tobias

PS: Usage example once fully implemented:

void f(omp_interop_t);
#pragma omp declare variant(f) \
   match(construct={dispatch}) \
   append_args(interop(targetsync))
void g();
...
omp_interop_t obj_tgtsync;
...
#pragma omp dispatch interop(obj_tgtsync)
  g (); // calls  f(obj_tgtsync)

#pragma omp dispatch
  g ();  // does:
// #pragma omp interop init(targetsync: tmp)
//   f(tmp)
// #pragma omp interop destroy(tmp)
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.

 c-family/c-pragma.h                       |    1 
 c/c-parser.cc                             |   17 ++++++
 c/c-typeck.cc                             |   23 ++++++--
 cp/parser.cc                              |   10 +++
 cp/pt.cc                                  |    1 
 cp/semantics.cc                           |   29 +++++++---
 gimplify.cc                               |   15 +++++
 testsuite/c-c++-common/gomp/dispatch-11.c |   84 ++++++++++++++++++++++++++++++
 testsuite/c-c++-common/gomp/dispatch-12.c |   53 ++++++++++++++++++
 tree-core.h                               |    3 +
 tree-pretty-print.cc                      |    6 +-
 tree.cc                                   |    2 
 12 files changed, 228 insertions(+), 16 deletions(-)
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index c95a602a475..df5625d5f4f 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -134,6 +134,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/c-parser.cc b/gcc/c/c-parser.cc
index ca4a6b39b27..f3ed6104747 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -15786,6 +15786,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))
@@ -20569,6 +20571,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.  */
 
@@ -21076,6 +21088,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);
 	  c_name = "map";
@@ -25078,6 +25094,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 f6f63ca7980..970fe68434b 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -17091,16 +17091,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/parser.cc b/gcc/cp/parser.cc
index fa9945b07da..f449ebde744 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -38335,6 +38335,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;
@@ -43336,6 +43338,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";
@@ -49728,6 +49737,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 74d0d86f560..5b7918805a3 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -17893,6 +17893,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 1ac6f6a76fb..30b0a4ea1de 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -9448,20 +9448,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 d6612a845de..7b2466a2e34 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -4071,6 +4071,20 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
      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)
     {
@@ -13400,6 +13414,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_ORDER:
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 620d0ad92e1..1776c154d94 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -387,6 +387,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 c50aa04c833..cacef9457e6 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -1578,7 +1578,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 40ebfa130de..6350dd42779 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  */
@@ -375,6 +376,7 @@ const char * const omp_clause_code_name[] =
   "destroy",
   "init",
   "use",
+  "interop",
   "gang",
   "async",
   "wait",
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 00000000000..7f1d8062f25
--- /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 00000000000..ea190c74e84
--- /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 } */
+}

Reply via email to