From: Sebastian Galindo <[email protected]>

This patch add OpenACC init,set,shutdown directives support for the C
and C++ front-ends.

An unexpected runtime error was fixed: When the device_type clause had
the argument as *, the set directive was passing an invalid argument to
the runtime library.

The bug 126507 was resolved (dtype alias for device_type).

gcc/c-family/ChangeLog:

        * c-common.h (c_finish_oacc_executable_directive): Declare.
        * c-omp.cc (oacc_eval_device_type): New.
        (c_finish_oacc_executable_directive): New.  Lower init, set and
        shutdown to GOACC builtins; map set's device_type(*) to
        GOMP_DEVICE_DEFAULT.
        * c-pragma.cc (oacc_pragmas): Register init, set and shutdown.
        * c-pragma.h (enum pragma_kind): Add PRAGMA_OACC_INIT,
        PRAGMA_OACC_SET and PRAGMA_OACC_SHUTDOWN.
        (enum pragma_omp_clause): Add PRAGMA_OACC_CLAUSE_DEVICE_NUM and
        PRAGMA_OACC_CLAUSE_DEVICE_TYPE alias.

gcc/c/ChangeLog:

        * c-parser.cc (c_parser_omp_clause_name): Recognize device_num and
        dtype as an alias of device_type.
        (c_parser_oacc_single_int_clause): Allow device_num 0; clamp
        non-positive device_num to 0.
        (c_parser_oacc_clause_device_type): New.  Parse OpenACC
        device_type/dtype arguments.
        (c_parser_oacc_all_clauses): Handle DEVICE_NUM and OpenACC
        DEVICE_TYPE.
        (OACC_INIT_CLAUSE_MASK, OACC_SHUTDOWN_CLAUSE_MASK,
        OACC_SET_CLAUSE_MASK): New.
        (c_parser_oacc_executable_directive): New.
        (c_parser_omp_construct): Handle init, set and shutdown.
        * c-typeck.cc (c_finish_omp_clauses): Accept OMP_CLAUSE_DEVICE_NUM.

gcc/cp/ChangeLog:

        * parser.cc (cp_parser_omp_clause_name): Recognize device_num and
        dtype as an alias of device_type.
        (cp_parser_oacc_single_int_clause): Allow device_num 0; clamp
        non-positive device_num to 0.
        (cp_parser_oacc_clause_device_type): New.  Parse OpenACC
        device_type/dtype arguments.
        (cp_parser_oacc_all_clauses): Handle DEVICE_NUM and OpenACC
        DEVICE_TYPE.
        (OACC_INIT_CLAUSE_MASK, OACC_SHUTDOWN_CLAUSE_MASK,
        OACC_SET_CLAUSE_MASK): New.
        (cp_parser_oacc_executable_directive): New.
        (cp_parser_omp_construct): Handle init, set and shutdown.
        (cp_parser_pragma): Allow init, set and shutdown in statement
        context.
        * semantics.cc (finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_NUM
        like other integral OpenACC clauses, including template
        instantiation; require a non-negative value.

gcc/fortran/ChangeLog:

        * openmp.cc (gfc_match_omp_clauses): Accept dtype as an alias of
        OpenACC device_type.
        * trans-openmp.cc (gfc_trans_oacc_executable_directive): For set,
        map device_type(*) to GOMP_DEVICE_DEFAULT.

gcc/ChangeLog:

        * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DEVICE_NUM.
        (enum oacc_clause_device_type_kind): New.
        (struct tree_omp_clause): Add oacc_device_type_kind.
        * tree-pretty-print.cc (dump_omp_clause): Dump DEVICE_NUM and
        OpenACC DEVICE_TYPE kinds.
        * tree.cc (omp_clause_num_ops, omp_clause_code_name): Handle
        DEVICE_NUM.
        * tree.h (OMP_CLAUSE_OACC_DEVICE_TYPE_KIND): Define.

gcc/testsuite/ChangeLog:

        * c-c++-common/goacc/uninit-if-clause.c: Test uninitialized if on
        init.
        * c-c++-common/goacc/update-if_present-2.c: Expect errors for
        if_present on init and shutdown.
        * gfortran.dg/goacc/acc-set-1.f90: Test set with device_type(*).
        * c-c++-common/goacc/acc-dtype-1.c: New test.
        * c-c++-common/goacc/acc-init-1.c: New test.
        * c-c++-common/goacc/acc-init-clauses-1.c: New test.
        * c-c++-common/goacc/acc-set-1.c: New test.
        * c-c++-common/goacc/acc-set-clauses-1.c: New test.
        * c-c++-common/goacc/acc-shutdown-1.c: New test.
        * c-c++-common/goacc/acc-shutdown-clauses-1.c: New test.
        * gfortran.dg/goacc/acc-dtype-1.f90: New test.

Signed-off-by: Sebastian Galindo <[email protected]>
---
This is a forge pull request published on the gcc-patches mailing list mailing 
list
as requested by Sebastian Galindo via Sourceware Forge 
<[email protected]>.
Forge discussion: https://forge.sourceware.org/gcc/gcc/pulls/225

Get it locally using:
```
git fetch forge-upstream "+refs/versioned_pull/225/*:refs/versioned_pull/225/*"
git switch -c "pr-225-v1" "refs/versioned_pull/225/1/head"
```
Or, download the patch at: https://forge.sourceware.org/gcc/gcc/pulls/225.diff
Created on: 2026-08-25 14:50:28+00:00
Latest update: 2026-08-27 03:11:30+00:00
Changes: 25 changed files, 939 additions, 26 deletions
Head revision: galindos/gcc-fork-galindos ref 
talkysafe/wip/init_set_shutdown/c_cpp commit 
4d1ae1abe734ff7cd607af9a1d5b4141b7b906f4 
Base revision: gcc/gcc ref trunk commit 
b085ae4b49b41e146c0a6a6c16c8c588438b9528 r17-3637-gb085ae4b49b41e
Merge base: b085ae4b49b41e146c0a6a6c16c8c588438b9528
Requested Reviewers: 

Changed files:
- A: gcc/testsuite/c-c++-common/goacc/acc-dtype-1.c
- A: gcc/testsuite/c-c++-common/goacc/acc-init-1.c
- A: gcc/testsuite/c-c++-common/goacc/acc-init-clauses-1.c
- A: gcc/testsuite/c-c++-common/goacc/acc-set-1.c
- A: gcc/testsuite/c-c++-common/goacc/acc-set-clauses-1.c
- A: gcc/testsuite/c-c++-common/goacc/acc-shutdown-1.c
- A: gcc/testsuite/c-c++-common/goacc/acc-shutdown-clauses-1.c
- A: gcc/testsuite/gfortran.dg/goacc/acc-dtype-1.f90
- M: gcc/c-family/c-common.h
- M: gcc/c-family/c-omp.cc
- M: gcc/c-family/c-pragma.cc
- M: gcc/c-family/c-pragma.h
- M: gcc/c/c-parser.cc
- M: gcc/c/c-typeck.cc
- M: gcc/cp/parser.cc
- M: gcc/cp/semantics.cc
- M: gcc/fortran/openmp.cc
- M: gcc/fortran/trans-openmp.cc
- M: gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
- M: gcc/testsuite/c-c++-common/goacc/update-if_present-2.c
- M: gcc/testsuite/gfortran.dg/goacc/acc-set-1.f90
- M: gcc/tree-core.h
- M: gcc/tree-pretty-print.cc
- M: gcc/tree.cc
- M: gcc/tree.h

 gcc/c-family/c-common.h                       |   1 +
 gcc/c-family/c-omp.cc                         |  94 ++++++++++
 gcc/c-family/c-pragma.cc                      |   3 +
 gcc/c-family/c-pragma.h                       |   5 +
 gcc/c/c-parser.cc                             | 163 +++++++++++++++++-
 gcc/c/c-typeck.cc                             |   1 +
 gcc/cp/parser.cc                              | 152 +++++++++++++++-
 gcc/cp/semantics.cc                           |  35 +++-
 gcc/fortran/openmp.cc                         |   8 +-
 gcc/fortran/trans-openmp.cc                   |   7 +-
 .../c-c++-common/goacc/acc-dtype-1.c          |  40 +++++
 gcc/testsuite/c-c++-common/goacc/acc-init-1.c |  62 +++++++
 .../c-c++-common/goacc/acc-init-clauses-1.c   |  35 ++++
 gcc/testsuite/c-c++-common/goacc/acc-set-1.c  |  53 ++++++
 .../c-c++-common/goacc/acc-set-clauses-1.c    |  83 +++++++++
 .../c-c++-common/goacc/acc-shutdown-1.c       |  62 +++++++
 .../goacc/acc-shutdown-clauses-1.c            |  53 ++++++
 .../c-c++-common/goacc/uninit-if-clause.c     |  12 +-
 .../c-c++-common/goacc/update-if_present-2.c  |   4 +-
 .../gfortran.dg/goacc/acc-dtype-1.f90         |  36 ++++
 gcc/testsuite/gfortran.dg/goacc/acc-set-1.f90 |   7 +
 gcc/tree-core.h                               |  16 +-
 gcc/tree-pretty-print.cc                      |  25 ++-
 gcc/tree.cc                                   |   4 +-
 gcc/tree.h                                    |   4 +
 25 files changed, 939 insertions(+), 26 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/goacc/acc-dtype-1.c
 create mode 100644 gcc/testsuite/c-c++-common/goacc/acc-init-1.c
 create mode 100644 gcc/testsuite/c-c++-common/goacc/acc-init-clauses-1.c
 create mode 100644 gcc/testsuite/c-c++-common/goacc/acc-set-1.c
 create mode 100644 gcc/testsuite/c-c++-common/goacc/acc-set-clauses-1.c
 create mode 100644 gcc/testsuite/c-c++-common/goacc/acc-shutdown-1.c
 create mode 100644 gcc/testsuite/c-c++-common/goacc/acc-shutdown-clauses-1.c
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/acc-dtype-1.f90

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index b89a8477e7cef..cc076d3651a47 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1348,6 +1348,7 @@ extern bool c_omp_check_loop_iv_exprs (location_t, enum 
tree_code, tree, int,
                                       tree, tree, tree, walk_tree_lh);
 extern bool c_omp_check_loop_binding_exprs (tree, vec<tree> *);
 extern tree c_finish_oacc_wait (location_t, tree, tree);
+extern tree c_finish_oacc_executable_directive (location_t, tree, int);
 extern tree c_oacc_split_loop_clauses (tree, tree *, bool);
 extern void c_omp_split_clauses (location_t, enum tree_code, omp_clause_mask,
                                 tree, tree *);
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 006e54d1e3d98..81ccfbc560d66 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -81,6 +81,100 @@ c_finish_oacc_wait (location_t loc, tree parms, tree 
clauses)
   return stmt;
 }
 
+/* Evals the oacc_clause_device_type_kind into the corresponding
+   device declaration in include/gomp-constants.h.  */
+int
+oacc_eval_device_type (oacc_clause_device_type_kind kind)
+{
+  switch (kind)
+    {
+    case OACC_CLAUSE_DEVICE_TYPE_NONE:
+      return GOMP_DEVICE_NONE;
+    case OACC_CLAUSE_DEVICE_TYPE_HOST:
+      return GOMP_DEVICE_HOST;
+    case OACC_CLAUSE_DEVICE_TYPE_NVIDIA:
+      return GOMP_DEVICE_NVIDIA_PTX;
+    case OACC_CLAUSE_DEVICE_TYPE_RADEON:
+      return GOMP_DEVICE_GCN;
+    default:
+      gcc_unreachable ();
+    }
+  return -1;
+}
+
+/* Complete a #pragma acc {init,set,shutdown} contruct.
+   LOC is the location of the #pragma.  */
+tree
+c_finish_oacc_executable_directive (location_t loc, tree clauses,
+                                   int oacc_pragma_kind)
+{
+  tree stmt, arg, dev_num, dev_type;
+  built_in_function builtin_kind;
+
+  switch ((pragma_kind) oacc_pragma_kind)
+    {
+      case PRAGMA_OACC_INIT:
+       builtin_kind = BUILT_IN_GOACC_INIT;
+       break;
+      case PRAGMA_OACC_SHUTDOWN:
+       builtin_kind = BUILT_IN_GOACC_SHUTDOWN;
+       break;
+      case PRAGMA_OACC_SET:
+       builtin_kind = BUILT_IN_GOACC_SET_DEVICE;
+       break;
+    default:
+      gcc_unreachable ();
+      break;
+    }
+
+  stmt = builtin_decl_explicit (builtin_kind);
+
+  arg = omp_find_clause (clauses, OMP_CLAUSE_DEVICE_NUM);
+
+  if (arg)
+    dev_num = OMP_CLAUSE_OPERAND (arg, 0);
+  else
+    /* no 'device_num' clause specified by the user, we don't modify the value
+       of ICV 'acc-current-device-num-var' or we do not take any action in init
+       and shutdown directive using -1 value.  */
+    dev_num = build_int_cst (integer_type_node, -1);
+
+  arg = omp_find_clause (clauses, OMP_CLAUSE_DEVICE_TYPE);
+
+  /* GOMP_DEVICE_NONE is used to make the operation
+     in all the devices.
+
+     GOMP_DEVICE_DEFAULT is used in set directive
+     to do nothing if the clause do not appear.  */
+  int device_type_int = oacc_pragma_kind == PRAGMA_OACC_SET
+                         ? GOMP_DEVICE_DEFAULT
+                         : GOMP_DEVICE_NONE;
+
+  if (arg)
+    {
+      device_type_int
+       = oacc_eval_device_type (OMP_CLAUSE_OACC_DEVICE_TYPE_KIND (arg));
+      /* For set, device_type (*) means the default device, not "all".  */
+      if (device_type_int == GOMP_DEVICE_NONE
+         && oacc_pragma_kind == PRAGMA_OACC_SET)
+       device_type_int = GOMP_DEVICE_DEFAULT;
+    }
+
+  dev_type = build_int_cst (integer_type_node, device_type_int);
+
+  stmt = build_call_expr_loc (loc, stmt, 2, dev_num, dev_type);
+
+  /* If clause handling.  */
+  arg = omp_find_clause (clauses, OMP_CLAUSE_IF);
+  if (arg)
+    stmt = build3_loc (input_location, COND_EXPR, void_type_node,
+                      OMP_CLAUSE_IF_EXPR (arg), stmt, NULL_TREE);
+
+  add_stmt (stmt);
+
+  return stmt;
+}
+
 /* Complete a #pragma omp master construct.  STMT is the structured-block
    that follows the pragma.  LOC is the location of the #pragma.  */
 
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index d0d4ff69fd7c9..9b447d0f0e6cf 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -1544,11 +1544,14 @@ static const struct omp_pragma_def oacc_pragmas[] = {
   { "enter", PRAGMA_OACC_ENTER_DATA },
   { "exit", PRAGMA_OACC_EXIT_DATA },
   { "host_data", PRAGMA_OACC_HOST_DATA },
+  { "init", PRAGMA_OACC_INIT },
   { "kernels", PRAGMA_OACC_KERNELS },
   { "loop", PRAGMA_OACC_LOOP },
   { "parallel", PRAGMA_OACC_PARALLEL },
   { "routine", PRAGMA_OACC_ROUTINE },
   { "serial", PRAGMA_OACC_SERIAL },
+  { "set", PRAGMA_OACC_SET },
+  { "shutdown", PRAGMA_OACC_SHUTDOWN },
   { "update", PRAGMA_OACC_UPDATE },
   { "wait", PRAGMA_OACC_WAIT }
 };
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 5d28cb45c669e..5cd6b5eb641c2 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -34,11 +34,14 @@ enum pragma_kind {
   PRAGMA_OACC_ENTER_DATA,
   PRAGMA_OACC_EXIT_DATA,
   PRAGMA_OACC_HOST_DATA,
+  PRAGMA_OACC_INIT,
   PRAGMA_OACC_KERNELS,
   PRAGMA_OACC_LOOP,
   PRAGMA_OACC_PARALLEL,
   PRAGMA_OACC_ROUTINE,
   PRAGMA_OACC_SERIAL,
+  PRAGMA_OACC_SET,
+  PRAGMA_OACC_SHUTDOWN,
   PRAGMA_OACC_UPDATE,
   PRAGMA_OACC_WAIT,
 
@@ -187,6 +190,7 @@ enum pragma_omp_clause {
   PRAGMA_OACC_CLAUSE_CREATE,
   PRAGMA_OACC_CLAUSE_DELETE,
   PRAGMA_OACC_CLAUSE_DEVICEPTR,
+  PRAGMA_OACC_CLAUSE_DEVICE_NUM,
   PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT,
   PRAGMA_OACC_CLAUSE_FINALIZE,
   PRAGMA_OACC_CLAUSE_GANG,
@@ -208,6 +212,7 @@ enum pragma_omp_clause {
   PRAGMA_OACC_CLAUSE_COLLAPSE = PRAGMA_OMP_CLAUSE_COLLAPSE,
   PRAGMA_OACC_CLAUSE_COPYIN = PRAGMA_OMP_CLAUSE_COPYIN,
   PRAGMA_OACC_CLAUSE_DEVICE = PRAGMA_OMP_CLAUSE_DEVICE,
+  PRAGMA_OACC_CLAUSE_DEVICE_TYPE = PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
   PRAGMA_OACC_CLAUSE_DEFAULT = PRAGMA_OMP_CLAUSE_DEFAULT,
   PRAGMA_OACC_CLAUSE_DETACH = PRAGMA_OMP_CLAUSE_DETACH,
   PRAGMA_OACC_CLAUSE_FIRSTPRIVATE = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 9dc5ba1e3a13f..6744306d51be0 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -1894,6 +1894,9 @@ static struct c_expr c_parser_has_attribute_expression 
(c_parser *);
 static void c_parser_oacc_declare (c_parser *);
 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
 static void c_parser_oacc_update (c_parser *);
+static tree c_parser_oacc_executable_directive (location_t, c_parser *,
+                                               pragma_kind, omp_clause_mask,
+                                               const char *);
 static void c_parser_omp_construct (c_parser *, bool *);
 static void c_parser_omp_groupprivate (c_parser *);
 static void c_parser_omp_threadprivate (c_parser *);
@@ -16524,9 +16527,11 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_DEVICE;
          else if (!strcmp ("deviceptr", p))
            result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
+         else if (!strcmp ("device_num", p))
+           result = PRAGMA_OACC_CLAUSE_DEVICE_NUM;
          else if (!strcmp ("device_resident", p))
            result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
-         else if (!strcmp ("device_type", p))
+         else if (!strcmp ("device_type", p) || !strcmp ("dtype", p))
            result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
          else if (!strcmp ("dist_schedule", p))
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
@@ -18370,7 +18375,8 @@ c_parser_omp_clause_is_device_ptr (c_parser *parser, 
tree list)
 /* OpenACC:
    num_gangs ( expression )
    num_workers ( expression )
-   vector_length ( expression )  */
+   vector_length (expression)
+   device_num (expression)  */
 
 static tree
 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
@@ -18399,16 +18405,23 @@ c_parser_oacc_single_int_clause (c_parser *parser, 
omp_clause_code code,
       return list;
     }
 
-  /* Attempt to statically determine when the number isn't positive.  */
-  c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
-                      build_int_cst (TREE_TYPE (t), 0));
+  bool nonneg_p = code == OMP_CLAUSE_DEVICE_NUM;
+
+  /* Attempt to statically determine when the number isn't positive.
+     device_num accepts 0 as argument.  */
+  c = fold_build2_loc (expr_loc,
+                      (nonneg_p ? LT_EXPR : LE_EXPR),
+                      boolean_type_node, t, build_int_cst (TREE_TYPE (t), 0));
   protected_set_expr_location (c, expr_loc);
   if (c == boolean_true_node)
     {
       warning_at (expr_loc, 0,
-                 "%qs value must be positive",
+                 (nonneg_p ? G_ ("%qs value must be non-negative")
+                           : G_ ("%qs value must be positive")),
                  omp_clause_code_name[code]);
       t = integer_one_node;
+      if (nonneg_p)
+       t = integer_zero_node;
     }
 
   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
@@ -21315,6 +21328,58 @@ c_parser_omp_clause_device_type (c_parser *parser, 
tree list)
   return list;
 }
 
+/* OpenACC 2.5:
+   device_type (host | nvidia | radeon | *) */
+
+static tree
+c_parser_oacc_clause_device_type (c_parser *parser, tree list)
+{
+  location_t clause_loc = c_parser_peek_token (parser)->location;
+  enum oacc_clause_device_type_kind kind;
+
+  tree c;
+  matching_parens parens;
+
+  if (!parens.require_open (parser))
+    return c;
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *name
+       = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      if (!strcmp ("host", name))
+       kind = OACC_CLAUSE_DEVICE_TYPE_HOST;
+      else if (!strcmp ("nvidia", name))
+       kind = OACC_CLAUSE_DEVICE_TYPE_NVIDIA;
+      else if (!strcmp ("radeon", name))
+       kind = OACC_CLAUSE_DEVICE_TYPE_RADEON;
+      else
+       goto invalid_kind;
+    }
+  else if (c_parser_next_token_is (parser, CPP_MULT))
+    {
+      kind = OACC_CLAUSE_DEVICE_TYPE_NONE;
+    }
+  else
+    goto invalid_kind;
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type");
+  c_parser_consume_token (parser);
+
+  parens.skip_until_found_close (parser);
+  c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
+  OMP_CLAUSE_OACC_DEVICE_TYPE_KIND (c) = kind;
+  OMP_CLAUSE_CHAIN (c) = list;
+
+  return c;
+
+invalid_kind:
+  c_parser_error (parser, "expected %<host%>, %<nvidia%>, %<radeon%> or 
%<*%>");
+  parens.skip_until_found_close (parser);
+  return list;
+}
+
 /* OpenMP 4.0:
    from ( variable-list )
    to ( variable-list )
@@ -22169,10 +22234,20 @@ c_parser_oacc_all_clauses (c_parser *parser, 
omp_clause_mask mask,
          clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
          c_name = "deviceptr";
          break;
+       case PRAGMA_OACC_CLAUSE_DEVICE_NUM:
+         clauses
+           = c_parser_oacc_single_int_clause (parser, OMP_CLAUSE_DEVICE_NUM,
+                                              clauses);
+         c_name = "device_num";
+         break;
        case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
          clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
          c_name = "device_resident";
          break;
+       case PRAGMA_OACC_CLAUSE_DEVICE_TYPE:
+         clauses = c_parser_oacc_clause_device_type (parser, clauses);
+         c_name = "device_type";
+         break;
        case PRAGMA_OACC_CLAUSE_FINALIZE:
          clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
                                                 clauses);
@@ -23508,6 +23583,61 @@ c_parser_oacc_wait (location_t loc, c_parser *parser, 
char *p_name)
   return stmt;
 }
 
+/* OpenACC 2.5:
+
+  #pragma acc init oacc-init-clause[optseq] new-line
+*/
+
+#define OACC_INIT_CLAUSE_MASK                                  \
+      ((OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)            \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_NUM)   \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_TYPE))
+
+/* OpenACC 2.5:
+
+  #pragma acc shutdown oacc-shutdown-clause[optseq] new-line
+*/
+
+#define OACC_SHUTDOWN_CLAUSE_MASK                                      \
+      ((OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)            \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_NUM)   \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_TYPE))
+
+
+/* OpenACC 2.5:
+
+  #pragma acc set oacc-set-clause[optseq] new-line
+*/
+
+#define OACC_SET_CLAUSE_MASK                                   \
+      ((OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)            \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_NUM)   \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_TYPE))
+
+
+static tree
+c_parser_oacc_executable_directive (location_t loc, c_parser *parser,
+                                   pragma_kind oacc_pragma_kind,
+                                   omp_clause_mask clause_mask,
+                                   const char *where)
+{
+  tree clauses;
+  clauses = c_parser_oacc_all_clauses (parser, clause_mask, where);
+
+  if (oacc_pragma_kind == PRAGMA_OACC_SET
+      && !omp_find_clause (clauses, OMP_CLAUSE_DEVICE_NUM)
+      && !omp_find_clause (clauses, OMP_CLAUSE_DEVICE_TYPE))
+    {
+      error_at (loc,
+               "%<#pragma acc set%> must contain at least one "
+               "%<device_type%> or %<device_num%> clause");
+      return NULL;
+    }
+
+  return c_finish_oacc_executable_directive (loc, clauses,
+                                            (int) oacc_pragma_kind);
+}
+
 struct c_omp_loc_tree
 {
   location_t loc;
@@ -31098,6 +31228,27 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
     case PRAGMA_OACC_HOST_DATA:
       stmt = c_parser_oacc_host_data (loc, parser, if_p);
       break;
+    case PRAGMA_OACC_INIT:
+      strcpy (p_name, "#pragma acc");
+      stmt = c_parser_oacc_executable_directive (loc, parser, PRAGMA_OACC_INIT,
+                                                OACC_INIT_CLAUSE_MASK,
+                                                "#pragma acc init");
+      break;
+    case PRAGMA_OACC_SET:
+      strcpy (p_name, "#pragma acc");
+      stmt = c_parser_oacc_executable_directive (loc, parser, PRAGMA_OACC_SET,
+                                                OACC_SET_CLAUSE_MASK,
+                                                "#pragma acc set");
+      break;
+
+    case PRAGMA_OACC_SHUTDOWN:
+      strcpy (p_name, "#pragma acc");
+      stmt
+       = c_parser_oacc_executable_directive (loc, parser, PRAGMA_OACC_SHUTDOWN,
+                                             OACC_SHUTDOWN_CLAUSE_MASK,
+                                             "#pragma acc shutdown");
+      break;
+
     case PRAGMA_OACC_KERNELS:
     case PRAGMA_OACC_PARALLEL:
     case PRAGMA_OACC_SERIAL:
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index ed234f075ca84..fb5ead434a7d0 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -18164,6 +18164,7 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
        case OMP_CLAUSE_TASKGROUP:
        case OMP_CLAUSE_PROC_BIND:
        case OMP_CLAUSE_DEVICE_TYPE:
+       case OMP_CLAUSE_DEVICE_NUM:
        case OMP_CLAUSE_PRIORITY:
        case OMP_CLAUSE_THREADS:
        case OMP_CLAUSE_SIMD:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index d3de58f182feb..63bb78c71667d 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -41495,9 +41495,11 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_DEVICE;
          else if (!strcmp ("deviceptr", p))
            result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
+         else if (!strcmp ("device_num", p))
+           result = PRAGMA_OACC_CLAUSE_DEVICE_NUM;
          else if (!strcmp ("device_resident", p))
            result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
-         else if (!strcmp ("device_type", p))
+         else if (!strcmp ("device_type", p) || !strcmp ("dtype", p))
            result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
          else if (!strcmp ("dist_schedule", p))
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
@@ -42305,7 +42307,8 @@ cp_parser_oacc_simple_clause (location_t loc, enum 
omp_clause_code code,
  /* OpenACC:
    num_gangs ( expression )
    num_workers ( expression )
-   vector_length ( expression )  */
+   vector_length (expression)
+   device_num (expression)  */
 
 static tree
 cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
@@ -46274,6 +46277,65 @@ cp_parser_omp_clause_device_type (cp_parser *parser, 
tree list,
   return list;
 }
 
+/* OpenACC 2.5:
+   device_type (host | nvidia | radeon | *) */
+
+static tree
+cp_parser_oacc_clause_device_type (cp_parser *parser, tree list,
+                                 location_t clause_loc)
+{
+  enum oacc_clause_device_type_kind kind;
+  tree c;
+
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+    return list;
+
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+
+      const char *name = IDENTIFIER_POINTER (id);
+
+      if (!strcmp ("host", name))
+       kind = OACC_CLAUSE_DEVICE_TYPE_HOST;
+      else if (!strcmp ("nvidia", name))
+       kind = OACC_CLAUSE_DEVICE_TYPE_NVIDIA;
+      else if (!strcmp ("radeon", name))
+       kind = OACC_CLAUSE_DEVICE_TYPE_RADEON;
+      else
+       goto invalid_kind;
+    }
+  else if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
+    {
+      kind = OACC_CLAUSE_DEVICE_TYPE_NONE;
+    }
+  else
+    goto invalid_kind;
+
+  cp_lexer_consume_token (parser->lexer);
+
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+    goto resync_fail;
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type",
+                            clause_loc);
+  c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
+
+  OMP_CLAUSE_OACC_DEVICE_TYPE_KIND (c) = kind;
+  OMP_CLAUSE_CHAIN (c) = list;
+
+  return c;
+
+invalid_kind:
+  cp_parser_error (parser,
+                  "expected %<host%>, %<nvidia%>, %<radeon%> or %<*%>");
+resync_fail:
+  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                        /*or_comma=*/false,
+                                        /*consume_paren=*/true);
+  return list;
+}
+
 /* OpenMP 5.1:
      prefer_type ( const-int-expr-or-string-literal-list )
 
@@ -46850,6 +46912,16 @@ cp_parser_oacc_all_clauses (cp_parser *parser, 
omp_clause_mask mask,
          clauses = cp_parser_oacc_data_clause_deviceptr (parser, clauses);
          c_name = "deviceptr";
          break;
+       case PRAGMA_OACC_CLAUSE_DEVICE_NUM:
+         code = OMP_CLAUSE_DEVICE_NUM;
+         c_name = "device_num";
+         clauses
+           = cp_parser_oacc_single_int_clause (parser, code, c_name, clauses);
+         break;
+       case PRAGMA_OACC_CLAUSE_DEVICE_TYPE:
+         c_name = "device_type";
+         clauses = cp_parser_oacc_clause_device_type (parser, clauses, here);
+         break;
        case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
          clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
          c_name = "device_resident";
@@ -53157,6 +53229,61 @@ cp_parser_oacc_wait (cp_parser *parser, cp_token 
*pragma_tok)
   return stmt;
 }
 
+/* OpenACC 2.5:
+
+  #pragma acc init oacc-init-clause[optseq] new-line
+*/
+
+#define OACC_INIT_CLAUSE_MASK                                  \
+      ((OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)            \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_NUM)   \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_TYPE))
+
+/* OpenACC 2.5:
+
+  #pragma acc shutdown oacc-shutdown-clause[optseq] new-line
+*/
+
+#define OACC_SHUTDOWN_CLAUSE_MASK                                      \
+      ((OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)            \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_NUM)   \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_TYPE))
+
+
+/* OpenACC 2.5:
+
+  #pragma acc set oacc-set-clause[optseq] new-line
+*/
+
+#define OACC_SET_CLAUSE_MASK                                   \
+      ((OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)            \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_NUM)   \
+      | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_TYPE))
+
+static tree
+cp_parser_oacc_executable_directive (cp_parser *parser,
+                                    pragma_kind oacc_pragma_kind,
+                                    omp_clause_mask clause_mask,
+                                    const char *where, cp_token *pragma_tok)
+{
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+  tree clauses;
+  clauses = cp_parser_oacc_all_clauses (parser, clause_mask, where, 
pragma_tok);
+
+  if (oacc_pragma_kind == PRAGMA_OACC_SET
+      && !omp_find_clause (clauses, OMP_CLAUSE_DEVICE_NUM)
+      && !omp_find_clause (clauses, OMP_CLAUSE_DEVICE_TYPE))
+    {
+      error_at (loc,
+               "%<#pragma acc set%> must contain at least one "
+               "%<device_type%> or %<device_num%> clause");
+      return NULL;
+    }
+
+  return c_finish_oacc_executable_directive (loc, clauses,
+                                            (int) oacc_pragma_kind);
+}
+
 /* OpenMP 4.0:
    # pragma omp declare simd declare-simd-clauses[optseq] new-line  */
 
@@ -56877,12 +57004,30 @@ cp_parser_omp_construct (cp_parser *parser, cp_token 
*pragma_tok, bool *if_p)
     case PRAGMA_OACC_HOST_DATA:
       stmt = cp_parser_oacc_host_data (parser, pragma_tok, if_p);
       break;
+    case PRAGMA_OACC_INIT:
+      stmt
+       = cp_parser_oacc_executable_directive (parser, PRAGMA_OACC_INIT,
+                                              OACC_INIT_CLAUSE_MASK,
+                                              "#pragma acc init", pragma_tok);
+      break;
     case PRAGMA_OACC_KERNELS:
     case PRAGMA_OACC_PARALLEL:
     case PRAGMA_OACC_SERIAL:
       strcpy (p_name, "#pragma acc");
       stmt = cp_parser_oacc_compute (parser, pragma_tok, p_name, if_p);
       break;
+    case PRAGMA_OACC_SET:
+      stmt
+       = cp_parser_oacc_executable_directive (parser, PRAGMA_OACC_SET,
+                                              OACC_SET_CLAUSE_MASK,
+                                              "#pragma acc set", pragma_tok);
+      break;
+    case PRAGMA_OACC_SHUTDOWN:
+      stmt = cp_parser_oacc_executable_directive (parser, PRAGMA_OACC_SHUTDOWN,
+                                                 OACC_SHUTDOWN_CLAUSE_MASK,
+                                                 "#pragma acc shutdown",
+                                                 pragma_tok);
+      break;
     case PRAGMA_OACC_LOOP:
       strcpy (p_name, "#pragma acc");
       stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask, NULL,
@@ -57616,6 +57761,9 @@ cp_parser_pragma (cp_parser *parser, enum 
pragma_context context, bool *if_p)
     case PRAGMA_OACC_LOOP:
     case PRAGMA_OACC_PARALLEL:
     case PRAGMA_OACC_SERIAL:
+    case PRAGMA_OACC_INIT:
+    case PRAGMA_OACC_SET:
+    case PRAGMA_OACC_SHUTDOWN:
     case PRAGMA_OMP_ASSUME:
     case PRAGMA_OMP_ATOMIC:
     case PRAGMA_OMP_CRITICAL:
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 7907668da36eb..f8b80fa5577be 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -7969,6 +7969,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type 
ort)
     {
       bool remove = false;
       bool field_ok = false;
+      bool non_negative = false;
 
       /* We've reached the end of a list of expanded nodes.  Reset the group
         start pointer.  */
@@ -8529,11 +8530,12 @@ finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
            num_tasks_seen = true;
          /* FALLTHRU */
 
+       case OMP_CLAUSE_DYN_GROUPPRIVATE:
+       case OMP_CLAUSE_DEVICE_NUM:
        case OMP_CLAUSE_NUM_TEAMS:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_NUM_GANGS:
        case OMP_CLAUSE_NUM_WORKERS:
-       case OMP_CLAUSE_DYN_GROUPPRIVATE:
        case OMP_CLAUSE_VECTOR_LENGTH:
          t = OMP_CLAUSE_OPERAND (c, 0);
          if (t == error_mark_node)
@@ -8554,6 +8556,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type 
ort)
                  error_at (OMP_CLAUSE_LOCATION (c),
                            "%<worker%> num expression must be integral");
                  break;
+               case OMP_CLAUSE_DEVICE_NUM:
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "%<device%> num expression must be integral");
+                 break;
                default:
                  error_at (OMP_CLAUSE_LOCATION (c),
                            "%qs expression must be integral",
@@ -8563,12 +8569,13 @@ finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
            }
          else
            {
+             non_negative = (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DYN_GROUPPRIVATE
+                             || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_NUM);
              t = mark_rvalue_use (t);
              if (!processing_template_decl)
                {
                  t = maybe_constant_value (t);
-                 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DYN_GROUPPRIVATE
-                     && TREE_CODE (t) == INTEGER_CST
+                 if (!non_negative && TREE_CODE (t) == INTEGER_CST
                      && tree_int_cst_sgn (t) != 1)
                    {
                      switch (OMP_CLAUSE_CODE (c))
@@ -8597,13 +8604,25 @@ finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
                        }
                      t = integer_one_node;
                    }
-                 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DYN_GROUPPRIVATE
-                          && TREE_CODE (t) == INTEGER_CST
+                 else if (non_negative && TREE_CODE (t) == INTEGER_CST
                           && tree_int_cst_sgn (t) < 0)
                    {
-                     warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
-                                 "%<dyn_groupprivate%> value must be "
-                                 "non-negative");
+                     switch (OMP_CLAUSE_CODE (c))
+                       {
+                       case OMP_CLAUSE_DEVICE_NUM:
+                         warning_at (OMP_CLAUSE_LOCATION (c), 0,
+                                     "%<device_num%> value must be "
+                                     "non-negative");
+                         break;
+                       case OMP_CLAUSE_DYN_GROUPPRIVATE:
+
+                         warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
+                                     "%<dyn_groupprivate%> value must be "
+                                     "non-negative");
+                         break;
+                       default:
+                         gcc_unreachable ();
+                       }
                      t = integer_zero_node;
                    }
                  t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index e559a2db0db9f..f28d48a8f32a5 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -3226,8 +3226,12 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const 
omp_mask mask,
                                           allow_derived))
            continue;
          if ((mask & OMP_CLAUSE_DEVICE_TYPE) && openacc
-             && gfc_match_dupl_check (!c->oacc_device_type_present,
-                                      "device_type", true) == MATCH_YES
+             && (gfc_match_dupl_check (!c->oacc_device_type_present,
+                                       "device_type", true)
+                   == MATCH_YES
+                 || gfc_match_dupl_check (!c->oacc_device_type_present,
+                                          "dtype", true)
+                      == MATCH_YES)
              && match_oacc_device_type (c) == MATCH_YES)
            continue;
          if ((mask & OMP_CLAUSE_DEVICE_TYPE) && !openacc
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 3e4375f6d6010..930027a2741f8 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -6568,7 +6568,12 @@ builtin_oacc_exec_directive:
                    GOMP_DEVICE_DEFAULT       :
                    GOMP_DEVICE_NONE;
   if (clauses->oacc_device_type_present)
-    device_type = clauses->oacc_device_type;
+    {
+      device_type = clauses->oacc_device_type;
+      /* For set, device_type (*) means the default device, not "all".  */
+      if (device_type == GOMP_DEVICE_NONE && code->op == EXEC_OACC_SET)
+       device_type = GOMP_DEVICE_DEFAULT;
+    }
 
   tree d_type = build_int_cst (integer_type_node, device_type);
 
diff --git a/gcc/testsuite/c-c++-common/goacc/acc-dtype-1.c 
b/gcc/testsuite/c-c++-common/goacc/acc-dtype-1.c
new file mode 100644
index 0000000000000..75b4229cbe102
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/acc-dtype-1.c
@@ -0,0 +1,40 @@
+/* Test OpenACC dtype abbreviation for device_type on init/set/shutdown.  */
+
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-original" } */
+
+void
+dtype_init (void)
+{
+  #pragma acc init dtype(host)
+}
+/* { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 2\\)" 1 
"original" } } */
+
+void
+dtype_init_star (void)
+{
+  #pragma acc init dtype(*)
+}
+/* { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 0\\)" 1 
"original" } } */
+
+void
+dtype_set_host (void)
+{
+  #pragma acc set dtype(nvidia)
+}
+/* { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 5\\)" 
1 "original" } } */
+
+void
+dtype_set_star (void)
+{
+  /* dtype(*) on set maps to GOMP_DEVICE_DEFAULT.  */
+  #pragma acc set dtype(*)
+}
+/* { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 1\\)" 
1 "original" } } */
+
+void
+dtype_shutdown (void)
+{
+  #pragma acc shutdown dtype(radeon) device_num(1)
+}
+/* { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(1, 8\\)" 1 
"original" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/acc-init-1.c 
b/gcc/testsuite/c-c++-common/goacc/acc-init-1.c
new file mode 100644
index 0000000000000..098ba7eda1128
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/acc-init-1.c
@@ -0,0 +1,62 @@
+// Test parsing and lowering of the OpenACC init directive.
+
+// { dg-do compile }
+// { dg-additional-options "-fdump-tree-original" }
+
+void
+init0 (void)
+{
+  #pragma acc init
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 0\\)" 2 
"original" { target c } } }
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 0\\)" 1 
"original" { target c++ } } }
+
+
+void
+init1 (void)
+{
+  #pragma acc init device_type(host)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 2\\)" 1 
"original" } }
+
+
+void
+init2 (void)
+{
+  #pragma acc init device_type(nvidia)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 5\\)" 1 
"original" } }
+
+
+void
+init3 (void)
+{
+  #pragma acc init device_num(0)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(0, 0\\)" 1 
"original" } }
+
+
+void
+init4 (void)
+{
+  #pragma acc init device_type(host) device_num(0)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(0, 2\\)" 1 
"original" } }
+
+
+void
+init5 (void)
+{
+  #pragma acc init if(false)
+}
+// { dg-final { scan-tree-dump-times "if \\(0\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ 
*__builtin_GOACC_init \\(-1, 0\\);" 1 "original" { target c } } }
+// { dg-final { scan-tree-dump-not "if \\(0\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ 
*__builtin_GOACC_init \\(-1, 0\\);" "original" { target c++ } } }
+
+
+void
+init6 (bool l)
+{
+  #pragma acc init if(l) device_type(radeon) device_num(1)
+}
+// { dg-final { scan-tree-dump-times "if \\(l != 0\\)\[\\n\\r\]+ 
*\{\[\\n\\r\]+ *__builtin_GOACC_init \\(1, 8\\);" 1 "original" { target c } } }
+// { dg-final { scan-tree-dump-times "if \\(l\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ 
*__builtin_GOACC_init \\(1, 8\\);" 1 "original" { target c++ } } }
diff --git a/gcc/testsuite/c-c++-common/goacc/acc-init-clauses-1.c 
b/gcc/testsuite/c-c++-common/goacc/acc-init-clauses-1.c
new file mode 100644
index 0000000000000..12f327388061f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/acc-init-clauses-1.c
@@ -0,0 +1,35 @@
+/* Test invalid clauses on the OpenACC init directive.  */
+
+/* { dg-do compile } */
+
+void
+bad1 (void)
+{
+#pragma acc init device_type(doesnt_exist) /* { dg-error "expected 'host', 
'nvidia', 'radeon' or '\\*'" } */
+}
+
+void
+bad2 (void)
+{
+#pragma acc init device_type(nvidia, host)
+  /* { dg-error "expected '\\\)' before ',' token" "" { target c } .-1 } */
+  /* { dg-error "expected '\\\,' or '\\\)'" "" { target c++ } .-2 } */
+}
+
+void
+bad3 (void)
+{
+#pragma acc init if_present /* { dg-error "'if_present' is not valid" } */
+}
+
+void
+bad4 (void)
+{
+#pragma acc init async /* { dg-error "'async' is not valid" } */
+}
+
+void
+bad5 (void)
+{
+#pragma acc init wait /* { dg-error "'wait' is not valid" } */
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/acc-set-1.c 
b/gcc/testsuite/c-c++-common/goacc/acc-set-1.c
new file mode 100644
index 0000000000000..5fc8cf2ea1ae7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/acc-set-1.c
@@ -0,0 +1,53 @@
+// Test parsing and lowering of the OpenACC set directive.
+
+// { dg-do compile }
+// { dg-additional-options "-fdump-tree-original" }
+
+void
+set0 (void)
+{
+  #pragma acc set device_type(host)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 2\\)" 
1 "original" } }
+
+
+void
+set1 (void)
+{
+  #pragma acc set device_type(nvidia)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 5\\)" 
1 "original" } }
+
+
+void
+set2 (void)
+{
+  #pragma acc set device_num(0)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(0, 1\\)" 1 
"original" } }
+
+
+void
+set3 (void)
+{
+  #pragma acc set device_type(host) device_num(0)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(0, 2\\)" 1 
"original" } }
+
+
+void
+set4 (bool l)
+{
+  #pragma acc set if(l) device_type(radeon) device_num(1)
+}
+// { dg-final { scan-tree-dump-times "if \\(l != 0\\)\[\\n\\r\]+ 
*\{\[\\n\\r\]+ *__builtin_GOACC_set_device \\(1, 8\\);" 1 "original" { target c 
} } }
+// { dg-final { scan-tree-dump-times "if \\(l\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ 
*__builtin_GOACC_set_device \\(1, 8\\);" 1 "original" { target c++ } } }
+
+
+void
+set5 (void)
+{
+  /* device_type(*) maps to GOMP_DEVICE_DEFAULT for set.  */
+  #pragma acc set device_type(*)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 1\\)" 
1 "original" } }
diff --git a/gcc/testsuite/c-c++-common/goacc/acc-set-clauses-1.c 
b/gcc/testsuite/c-c++-common/goacc/acc-set-clauses-1.c
new file mode 100644
index 0000000000000..ef92ae53b4421
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/acc-set-clauses-1.c
@@ -0,0 +1,83 @@
+/* Test invalid clauses on the OpenACC set directive.  */
+
+/* { dg-do compile } */
+
+void
+bad1 (void)
+{
+#pragma acc set device_type(doesnt_exist)
+  /* { dg-error "expected 'host', 'nvidia', 'radeon' or '\\*'" "" { target 
*-*-* } .-1 } */
+  /* { dg-error "'#pragma acc set' must contain at least one 'device_type' or 
'device_num' clause" "" { target *-*-* } .-2 } */
+}
+
+void
+bad2 (void)
+{
+#pragma acc set device_type(nvidia, host)
+  /* { dg-error "expected '\\\)' before ',' token" "" { target c } .-1 } */
+  /* { dg-error "expected '\\\,' or '\\\)'" "" { target c++ } .-2 } */
+  /* { dg-error "'#pragma acc set' must contain at least one 'device_type' or 
'device_num' clause" "" { target c++ } .-3 } */
+}
+
+void
+bad3 (void)
+{
+#pragma acc set /* { dg-error "'#pragma acc set' must contain at least one 
'device_type' or 'device_num' clause" } */
+}
+
+void
+bad4 (void)
+{
+#pragma acc set if(1) /* { dg-error "'#pragma acc set' must contain at least 
one 'device_type' or 'device_num' clause" } */
+}
+
+void
+bad5 (void)
+{
+#pragma acc set default_async(0)
+  /* { dg-error "expected an OpenACC clause before 'default_async'" "" { 
target *-*-* } .-1 } */
+  /* { dg-error "'#pragma acc set' must contain at least one 'device_type' or 
'device_num' clause" "" { target *-*-* } .-2 } */
+}
+
+void
+bad6 (void)
+{
+#pragma acc set if_present
+  /* { dg-error "'if_present' is not valid" "" { target *-*-* } .-1 } */
+  /* { dg-error "'#pragma acc set' must contain at least one 'device_type' or 
'device_num' clause" "" { target *-*-* } .-2 } */
+}
+
+void
+bad7 (void)
+{
+#pragma acc set async
+  /* { dg-error "'async' is not valid" "" { target *-*-* } .-1 } */
+  /* { dg-error "'#pragma acc set' must contain at least one 'device_type' or 
'device_num' clause" "" { target *-*-* } .-2 } */
+}
+
+void
+bad8 (void)
+{
+#pragma acc set wait
+  /* { dg-error "'wait' is not valid" "" { target *-*-* } .-1 } */
+  /* { dg-error "'#pragma acc set' must contain at least one 'device_type' or 
'device_num' clause" "" { target *-*-* } .-2 } */
+}
+
+void
+bad9 (void)
+{
+#pragma acc set device_type(host) device_type(nvidia) /* { dg-error "too many 
'device_type' clauses" } */
+}
+
+void
+bad10 (void)
+{
+#pragma acc set device_num(0) device_num(1) /* { dg-error "too many 
'device_num' clauses" } */
+}
+
+void
+bad11 (void)
+{
+#pragma acc set if(0) if(1) /* { dg-error "too many 'if' clauses" } */
+  /* { dg-error "'#pragma acc set' must contain at least one 'device_type' or 
'device_num' clause" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/acc-shutdown-1.c 
b/gcc/testsuite/c-c++-common/goacc/acc-shutdown-1.c
new file mode 100644
index 0000000000000..e88a34d0e5b1f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/acc-shutdown-1.c
@@ -0,0 +1,62 @@
+// Test parsing and lowering of the OpenACC shutdown directive.
+
+// { dg-do compile }
+// { dg-additional-options "-fdump-tree-original" }
+
+void
+shutdown0 (void)
+{
+  #pragma acc shutdown
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(-1, 0\\)" 2 
"original" { target c } } }
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(-1, 0\\)" 1 
"original" { target c++ } } }
+
+
+void
+shutdown1 (void)
+{
+  #pragma acc shutdown device_type(host)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(-1, 2\\)" 1 
"original" } }
+
+
+void
+shutdown2 (void)
+{
+  #pragma acc shutdown device_type(nvidia)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(-1, 5\\)" 1 
"original" } }
+
+
+void
+shutdown3 (void)
+{
+  #pragma acc shutdown device_num(0)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(0, 0\\)" 1 
"original" } }
+
+
+void
+shutdown4 (void)
+{
+  #pragma acc shutdown device_type(host) device_num(0)
+}
+// { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(0, 2\\)" 1 
"original" } }
+
+
+void
+shutdown5 (void)
+{
+  #pragma acc shutdown if(false)
+}
+// { dg-final { scan-tree-dump-times "if \\(0\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ 
*__builtin_GOACC_shutdown \\(-1, 0\\);" 1 "original" { target c } } }
+// { dg-final { scan-tree-dump-not "if \\(0\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ 
*__builtin_GOACC_shutdown \\(-1, 0\\);" "original" { target c++ } } }
+
+
+void
+shutdown6 (bool l)
+{
+  #pragma acc shutdown if(l) device_type(radeon) device_num(1)
+}
+// { dg-final { scan-tree-dump-times "if \\(l != 0\\)\[\\n\\r\]+ 
*\{\[\\n\\r\]+ *__builtin_GOACC_shutdown \\(1, 8\\);" 1 "original" { target c } 
} }
+// { dg-final { scan-tree-dump-times "if \\(l\\)\[\\n\\r\]+ *\{\[\\n\\r\]+ 
*__builtin_GOACC_shutdown \\(1, 8\\);" 1 "original" { target c++ } } }
diff --git a/gcc/testsuite/c-c++-common/goacc/acc-shutdown-clauses-1.c 
b/gcc/testsuite/c-c++-common/goacc/acc-shutdown-clauses-1.c
new file mode 100644
index 0000000000000..d1fdfd542cfac
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/acc-shutdown-clauses-1.c
@@ -0,0 +1,53 @@
+/* Test invalid clauses on the OpenACC shutdown directive.  */
+
+/* { dg-do compile } */
+
+void
+bad1 (void)
+{
+#pragma acc shutdown device_type(doesnt_exist) /* { dg-error "expected 'host', 
'nvidia', 'radeon' or '\\*'" } */
+}
+
+void
+bad2 (void)
+{
+#pragma acc shutdown device_type(nvidia, host)
+  /* { dg-error "expected '\\\)' before ',' token" "" { target c } .-1 } */
+  /* { dg-error "expected '\\\,' or '\\\)'" "" { target c++ } .-2 } */
+}
+
+void
+bad3 (void)
+{
+#pragma acc shutdown if_present /* { dg-error "'if_present' is not valid" } */
+}
+
+void
+bad4 (void)
+{
+#pragma acc shutdown async /* { dg-error "'async' is not valid" } */
+}
+
+void
+bad5 (void)
+{
+#pragma acc shutdown wait /* { dg-error "'wait' is not valid" } */
+}
+
+void
+bad6 (void)
+{
+#pragma acc shutdown device_type(host) device_type(nvidia) /* { dg-error "too 
many 'device_type' clauses" } */
+}
+
+void
+bad7 (void)
+{
+#pragma acc shutdown device_num(0) device_num(1) /* { dg-error "too many 
'device_num' clauses" } */
+}
+
+void
+bad8 (void)
+{
+#pragma acc shutdown if(0) if(1) /* { dg-error "too many 'if' clauses" } */
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c 
b/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
index d4738b9644254..904d868d3ebc1 100644
--- a/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
+++ b/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
@@ -6,18 +6,20 @@
 int
 main (void)
 {
-  int l, l2, ls, l3, l4;
+  int l, l2, ls, l3, l4, l5;
   /* { dg-note {'l' was declared here} {} { target *-*-* } .-1 } */
   /* { dg-note {'l2' was declared here} {} { target *-*-* } .-2 } */
   /* { dg-note {'ls' was declared here} {} { target *-*-* } .-3 } */
   /* { dg-note {'l3' was declared here} {} { target *-*-* } .-4 } */
   /* { dg-note {'l4' was declared here} {} { target *-*-* } .-5 } */
-  bool b, b2, bs, b3, b4;
+  /* { dg-note {'l5' was declared here} {} { target *-*-* } .-6 } */
+  bool b, b2, bs, b3, b4, b5;
   /* { dg-note {'b' was declared here} {} { target *-*-* } .-1 } */
   /* { dg-note {'b2' was declared here} {} { target *-*-* } .-2 } */
   /* { dg-note {'bs' was declared here} {} { target *-*-* } .-3 } */
   /* { dg-note {'b3' was declared here} {} { target *-*-* } .-4 } */
   /* { dg-note {'b4' was declared here} {} { target *-*-* } .-5 } */
+  /* { dg-note {'b5' was declared here} {} { target *-*-* } .-6 } */
   int i, i2;
 
   #pragma acc parallel if(l) /* { dg-warning "is used uninitialized" } */
@@ -50,4 +52,10 @@ main (void)
   #pragma acc update if(b4) self(i2) /* { dg-warning "is used uninitialized" } 
*/
   ;
 
+  #pragma acc init if(l5) /* { dg-warning "is used uninitialized" } */
+  ;
+
+  #pragma acc init if(b5) /* { dg-warning "is used uninitialized" } */
+  ;
+
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c 
b/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c
index 0fd1505ace8f0..3edc073420c5d 100644
--- a/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c
@@ -15,8 +15,8 @@ t1 ()
 
 #pragma acc declare create(c) if_present /* { dg-error "'if_present' is not 
valid" } */
 
-#pragma acc init if_present
-#pragma acc shutdown if_present
+#pragma acc init if_present /* { dg-error "'if_present' is not valid" } */
+#pragma acc shutdown if_present /* { dg-error "'if_present' is not valid" } */
 }
 
 void
diff --git a/gcc/testsuite/gfortran.dg/goacc/acc-dtype-1.f90 
b/gcc/testsuite/gfortran.dg/goacc/acc-dtype-1.f90
new file mode 100644
index 0000000000000..7688155476fa4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/acc-dtype-1.f90
@@ -0,0 +1,36 @@
+! Test OpenACC dtype abbreviation for device_type on init/set/shutdown.
+
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+
+subroutine dtype_init
+  implicit none
+  !$acc init dtype(host)
+end subroutine dtype_init
+
+subroutine dtype_init_star
+  implicit none
+  !$acc init dtype(*)
+end subroutine dtype_init_star
+
+subroutine dtype_set_host
+  implicit none
+  !$acc set dtype(nvidia)
+end subroutine dtype_set_host
+
+subroutine dtype_set_star
+  implicit none
+  ! dtype(*) on set maps to GOMP_DEVICE_DEFAULT.
+  !$acc set dtype(*)
+end subroutine dtype_set_star
+
+subroutine dtype_shutdown
+  implicit none
+  !$acc shutdown dtype(radeon) device_num(1)
+end subroutine dtype_shutdown
+
+! { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 2\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOACC_init \\(-1, 0\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 5\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 1\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOACC_shutdown \\(1, 8\\)" 1 
"original" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/acc-set-1.f90 
b/gcc/testsuite/gfortran.dg/goacc/acc-set-1.f90
index 013c301c775f4..5c9e3e3817d7d 100644
--- a/gcc/testsuite/gfortran.dg/goacc/acc-set-1.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/acc-set-1.f90
@@ -29,8 +29,15 @@ subroutine set4(l)
   !$acc set if(l) device_type(radeon) device_num(1)
 end subroutine set4
 
+subroutine set5
+  implicit none
+  ! device_type(*) maps to GOMP_DEVICE_DEFAULT for set.
+  !$acc set device_type(*)
+end subroutine set5
+
 ! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 2\\)" 1 
"original" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 5\\)" 1 
"original" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(0, 1\\)" 1 
"original" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(0, 2\\)" 1 
"original" } }
 ! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(1, 8\\)" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "__builtin_GOACC_set_device \\(-1, 1\\)" 1 
"original" } }
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 1687b1f946724..150d6f06282d7 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -608,7 +608,10 @@ enum omp_clause_code {
      stored in OMP_CLAUSE_MESSAGE_LEN.
      Note that the 'severity' clause is handled as flag to 'message':
      OMP_CLAUSE_MESSAGE_SEVERITY_WARN.  */
-  OMP_CLAUSE_MESSAGE
+  OMP_CLAUSE_MESSAGE,
+
+  /* OpenACC clause: device_num (integer-expression).  */
+  OMP_CLAUSE_DEVICE_NUM,
 };
 
 #undef DEFTREESTRUCT
@@ -1693,6 +1696,16 @@ enum omp_clause_device_type_kind
   OMP_CLAUSE_DEVICE_TYPE_ANY = 3
 };
 
+// OpenACC device_type shares code with OpenMP device_type, this numeration
+// ensure propper debug output.
+enum oacc_clause_device_type_kind
+{
+  OACC_CLAUSE_DEVICE_TYPE_NONE = 4,
+  OACC_CLAUSE_DEVICE_TYPE_HOST = 5,
+  OACC_CLAUSE_DEVICE_TYPE_NVIDIA = 6,
+  OACC_CLAUSE_DEVICE_TYPE_RADEON = 7,
+};
+
 enum omp_clause_linear_kind
 {
   OMP_CLAUSE_LINEAR_DEFAULT,
@@ -1773,6 +1786,7 @@ struct GTY(()) tree_omp_clause {
     enum omp_clause_bind_kind      bind_kind;
     enum omp_clause_device_type_kind device_type_kind;
     enum omp_clause_fallback_kind fallback_kind;
+    enum oacc_clause_device_type_kind oacc_device_type_kind;
   } GTY ((skip)) subcode;
 
   /* The gimplification of OMP_CLAUSE_REDUCTION_{INIT,MERGE} for omp-low's
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 316945c00ede3..0759fa456aa75 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -1377,6 +1377,12 @@ dump_omp_clause (pretty_printer *pp, tree clause, int 
spc, dump_flags_t flags)
       pp_right_paren (pp);
       break;
 
+    case OMP_CLAUSE_DEVICE_NUM:
+      pp_string (pp, "device_num (");
+      dump_generic_node (pp, OMP_CLAUSE_OPERAND (clause, 0), spc, flags, 
false);
+      pp_character (pp, ')');
+      break;
+
     case OMP_CLAUSE_DEVICE_TYPE:
       pp_string (pp, "device_type(");
       switch (OMP_CLAUSE_DEVICE_TYPE_KIND (clause))
@@ -1391,7 +1397,24 @@ dump_omp_clause (pretty_printer *pp, tree clause, int 
spc, dump_flags_t flags)
          pp_string (pp, "any");
          break;
        default:
-         gcc_unreachable ();
+         // In this case, should be the OpenACC variant.
+         switch (OMP_CLAUSE_OACC_DEVICE_TYPE_KIND (clause))
+           {
+           case OACC_CLAUSE_DEVICE_TYPE_NONE:
+             pp_string (pp, "*");
+             break;
+           case OACC_CLAUSE_DEVICE_TYPE_HOST:
+             pp_string (pp, "host");
+             break;
+           case OACC_CLAUSE_DEVICE_TYPE_NVIDIA:
+             pp_string (pp, "nvidia");
+             break;
+           case OACC_CLAUSE_DEVICE_TYPE_RADEON:
+             pp_string (pp, "radeon");
+             break;
+           default:
+             gcc_unreachable ();
+           }
        }
       pp_right_paren (pp);
       break;
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 69a7c7e6d34d4..1d43c3d35d5f5 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -401,6 +401,7 @@ unsigned const char omp_clause_num_ops[] =
   1, /* OMP_CLAUSE_DYN_GROUPPRIVATE  */
   3, /* OMP_CLAUSE_USES_ALLOCATORS */
   2, /* OMP_CLAUSE_MESSAGE */
+  1, /* OMP_CLAUSE_DEVICE_NUM.  */
 };
 
 const char * const omp_clause_code_name[] =
@@ -506,7 +507,8 @@ const char * const omp_clause_code_name[] =
   "nocontext",
   "dyn_groupprivate",
   "uses_allocators",
-  "message"
+  "message",
+  "device_num",
 };
 
 /* Unless specific to OpenACC, we tend to internally maintain OpenMP-centric
diff --git a/gcc/tree.h b/gcc/tree.h
index 3fb643ea0fb48..06c3287ccc506 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2015,6 +2015,10 @@ class auto_suppress_location_wrappers
 #define OMP_CLAUSE_DEVICE_TYPE_KIND(NODE) \
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, 
OMP_CLAUSE_DEVICE_TYPE)->omp_clause.subcode.device_type_kind)
 
+#define OMP_CLAUSE_OACC_DEVICE_TYPE_KIND(NODE) \
+  (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE_TYPE) \
+     ->omp_clause.subcode.oacc_device_type_kind)
+
 #define OMP_CLAUSE_INDIRECT_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_INDIRECT), 0)
 
-- 
2.54.0

Reply via email to