diff mbox series

Fortran: cleanup OpenMP's OMP_LIST_* handling

Message ID 895245d2-8621-759e-1a77-f83cd61652d8@codesourcery.com
State New
Headers show
Series Fortran: cleanup OpenMP's OMP_LIST_* handling | expand

Commit Message

Tobias Burnus Nov. 16, 2020, 2:08 p.m. UTC
Hi all,

as discussed the other day (I think via IRC or in a patch review),
   omp_list_clauses
did grow quite a bit: it has 26 entries and I am about to add two
more.

This variable is used as:
  typedef struct gfc_omp_clauses
  {
    ...
    gfc_omp_namelist *lists[OMP_LIST_NUM];

with sizeof(gfc_omp_namelist) = 5*sizeof(void*) + sizeof(locus);

This patch replaces it with a linked list.


I am not really sure the new version is that readable and whether
we move into the right direction or not.

Comments?

Tobias

PS: If the direction is sensible, a very careful reading of the
patch is probably useful.

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter

Comments

Jakub Jelinek Nov. 18, 2020, 11:14 a.m. UTC | #1
On Mon, Nov 16, 2020 at 03:08:36PM +0100, Tobias Burnus wrote:
> as discussed the other day (I think via IRC or in a patch review),
>   omp_list_clauses
> did grow quite a bit: it has 26 entries and I am about to add two
> more.
> 
> This variable is used as:
>  typedef struct gfc_omp_clauses
>  {
>    ...
>    gfc_omp_namelist *lists[OMP_LIST_NUM];
> 
> with sizeof(gfc_omp_namelist) = 5*sizeof(void*) + sizeof(locus);
> 
> This patch replaces it with a linked list.
> 
> 
> I am not really sure the new version is that readable and whether
> we move into the right direction or not.

> --- a/gcc/fortran/gfortran.h
> +++ b/gcc/fortran/gfortran.h
> @@ -1240,7 +1240,7 @@ enum gfc_omp_linear_op
>  /* For use in OpenMP clauses in case we need extra information
>     (aligned clause alignment, linear clause step, etc.).  */
>  
> -typedef struct gfc_omp_namelist
> +typedef struct gfc_omp_namelist_item
>  {
>    struct gfc_symbol *sym;
>    struct gfc_expr *expr;
> @@ -1254,17 +1254,16 @@ typedef struct gfc_omp_namelist
>        bool lastprivate_conditional;
>      } u;
>    struct gfc_omp_namelist_udr *udr;
> -  struct gfc_omp_namelist *next;
> +  struct gfc_omp_namelist_item *next;
>    locus where;
>  }
> -gfc_omp_namelist;
> +gfc_omp_namelist_item;
> +#define gfc_get_omp_namelist_item() XCNEW (gfc_omp_namelist_item)
>  
> -#define gfc_get_omp_namelist() XCNEW (gfc_omp_namelist)
> -
> -enum
> +enum omp_list_clauses
>  {
> -  OMP_LIST_FIRST,
> -  OMP_LIST_PRIVATE = OMP_LIST_FIRST,
> +  OMP_LIST_UNSET,
> +  OMP_LIST_PRIVATE,
>    OMP_LIST_FIRSTPRIVATE,
>    OMP_LIST_LASTPRIVATE,
>    OMP_LIST_COPYPRIVATE,
> @@ -1289,8 +1288,7 @@ enum
>    OMP_LIST_IS_DEVICE_PTR,
>    OMP_LIST_USE_DEVICE_PTR,
>    OMP_LIST_USE_DEVICE_ADDR,
> -  OMP_LIST_NONTEMPORAL,
> -  OMP_LIST_NUM
> +  OMP_LIST_NONTEMPORAL
>  };
>  
>  /* Because a symbol can belong to multiple namelists, they must be
> @@ -1386,12 +1384,22 @@ enum gfc_omp_memorder
>    OMP_MEMORDER_RELAXED
>  };
>  
> +typedef struct gfc_omp_namelist
> +{
> +  enum omp_list_clauses clause;
> +  gfc_omp_namelist_item *item;
> +  struct gfc_omp_namelist *next;
> +}
> +gfc_omp_namelist;

I meant something slightly different, in particular not
this gfc_omp_namelist vs. gfc_omp_namelist_item (i.e. linked list of linked
lists), but just a linked list, i.e. just add
  ENUM_BITFIELD (enum omp_list_clauses) clause : 16;
  int flags : 16;
into gfc_omp_namelist where the flags could hold various flags for certain
clauses, e.g. for OMP_LIST_LASTPRIVATE it could hold the conditional
modifier, for OMP_LIST_REDUCTION the inscan and task modifiers, etc.
Or do you see any advantages in having the same clauses for different
symbols adjacent in the FE?

	Jakub
diff mbox series

Patch

Fortran: cleanup OpenMP's OMP_LIST_* handling

gcc/fortran/ChangeLog:

	* dump-parse-tree.c (show_omp_namelist, show_omp_node): Update for
	new internal representation of gfc_omp_namelist.
	(show_omp_clauses): Likewise; replace own list by call to
	gfc_omp_get_clause_name.
	* frontend-passes.c (gfc_code_walker): Update gfc_omp_namelist handling.
	* gfortran.h (gfc_omp_namelist_item): Renamed from gfc_omp_namelist.
	(gfc_get_omp_namelist_item): Renamed from gfc_get_omp_namelist.
	(enum omp_list_clauses): Add name to enum, remove OMP_LIST_FIRST and
	OMP_LIST_NUM, add OMP_LIST_UNSET.
	(gfc_get_omp_namelist, gfc_omp_namelist): New.
	(gfc_omp_clauses): Use new gfc_get_omp_namelist.
	(gfc_code): Update for renaming.
	(gfc_free_omp_namelist_item): Renamed from gfc_free_omp_namelist and
	updated.
	(gfc_omp_get_clause_name, gfc_omp_get_nm_ref, gfc_omp_get_nm_list): New.
	* match.c (gfc_free_omp_namelist_item): Renamed from
	gfc_free_omp_namelist.
	* module.c (mio_omp_declare_simd): Update for gfc_omp_namelist changes.
	* openmp.c (gfc_free_omp_clauses, gfc_match_omp_variable_list,
	gfc_match_omp_to_link, gfc_match_omp_depend_sink,
	gfc_match_oacc_clause_link, gfc_match_omp_map_clause): Likewise.
	(gfc_omp_get_clause_name, gfc_omp_get_nm_ref, gfc_omp_get_nm_list): New.
	(gfc_match_omp_clause_reduction, gfc_match_omp_clauses,
	gfc_match_oacc_declare, gfc_match_oacc_update, gfc_match_oacc_cache,
	gfc_match_omp_flush, gfc_match_omp_declare_target,
	resolve_omp_udr_clause, resolve_omp_clauses,
	gfc_resolve_omp_parallel_blocks, gfc_resolve_do_iterator,
	resolve_omp_do, gfc_resolve_oacc_blocks, gfc_resolve_oacc_declare,
	gfc_resolve_omp_directive): Use new functions; update for
	gfc_omp_namelist changes.
	* parse.c (parse_omp_structured_block): Likewise
	* st.c (gfc_free_statement): Likewise
	* trans-decl.c (add_clause, finish_oacc_declare): Likewise.
	* trans-openmp.c (gfc_copy_list_clauses,
	gfc_trans_omp_free_clausea): New.
	(gfc_trans_omp_variable_list, gfc_trans_omp_array_reduction_or_udr,
	gfc_trans_omp_reduction_list, gfc_trans_omp_array_section,
	gfc_trans_omp_clauses, gfc_trans_omp_do,
	gfc_trans_oacc_combined_directive, gfc_split_omp_clauses,
	gfc_trans_omp_do_simd, gfc_trans_omp_parallel_do,
	gfc_trans_omp_parallel_do_simd, gfc_trans_omp_sections,
	gfc_trans_omp_distribute, gfc_trans_omp_teams, gfc_trans_omp_target,
	gfc_trans_omp_taskloop): Use them; update for gfc_omp_namelist changes.

gcc/testsuite/ChangeLog:

	* gfortran.dg/goacc/combined-directives.f90: Update scan-tree pattern.
	* gfortran.dg/goacc/reduction-2.f95: Likewise.
	* gfortran.dg/gomp/openmp-simd-6.f90: Likewise.
	* gfortran.dg/gomp/reduction4.f90: Likewise.

 gcc/fortran/dump-parse-tree.c                      |  57 +-
 gcc/fortran/frontend-passes.c                      |  14 +-
 gcc/fortran/gfortran.h                             |  40 +-
 gcc/fortran/match.c                                |   4 +-
 gcc/fortran/module.c                               |  31 +-
 gcc/fortran/openmp.c                               | 723 ++++++++++++---------
 gcc/fortran/parse.c                                |  10 +-
 gcc/fortran/st.c                                   |   2 +-
 gcc/fortran/trans-decl.c                           |  35 +-
 gcc/fortran/trans-openmp.c                         | 237 ++++---
 .../gfortran.dg/goacc/combined-directives.f90      |   5 +-
 gcc/testsuite/gfortran.dg/goacc/reduction-2.f95    |   4 +-
 gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90   |   4 +-
 gcc/testsuite/gfortran.dg/gomp/reduction4.f90      |   6 +-
 14 files changed, 666 insertions(+), 506 deletions(-)

diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index cab0fb2979f..7ddf4216361 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1273,7 +1273,7 @@  show_code (int level, gfc_code *c)
 }
 
 static void
-show_omp_namelist (int list_type, gfc_omp_namelist *n)
+show_omp_namelist (enum omp_list_clauses list_type, gfc_omp_namelist_item *n)
 {
   for (; n; n = n->next)
     {
@@ -1366,7 +1366,7 @@  show_omp_namelist (int list_type, gfc_omp_namelist *n)
 static void
 show_omp_clauses (gfc_omp_clauses *omp_clauses)
 {
-  int list_type, i;
+  int i;
 
   switch (omp_clauses->cancel)
     {
@@ -1567,48 +1567,16 @@  show_omp_clauses (gfc_omp_clauses *omp_clauses)
     fputs (" MERGEABLE", dumpfile);
   if (omp_clauses->collapse)
     fprintf (dumpfile, " COLLAPSE(%d)", omp_clauses->collapse);
-  for (list_type = 0; list_type < OMP_LIST_NUM; list_type++)
-    if (omp_clauses->lists[list_type] != NULL
-	&& list_type != OMP_LIST_COPYPRIVATE)
+  for (gfc_omp_namelist *list = omp_clauses->lists; list; list = list->next)
+    if (list->clause != OMP_LIST_COPYPRIVATE)
       {
-	const char *type = NULL;
-	switch (list_type)
-	  {
-	  case OMP_LIST_PRIVATE: type = "PRIVATE"; break;
-	  case OMP_LIST_FIRSTPRIVATE: type = "FIRSTPRIVATE"; break;
-	  case OMP_LIST_LASTPRIVATE: type = "LASTPRIVATE"; break;
-	  case OMP_LIST_COPYPRIVATE: type = "COPYPRIVATE"; break;
-	  case OMP_LIST_SHARED: type = "SHARED"; break;
-	  case OMP_LIST_COPYIN: type = "COPYIN"; break;
-	  case OMP_LIST_UNIFORM: type = "UNIFORM"; break;
-	  case OMP_LIST_ALIGNED: type = "ALIGNED"; break;
-	  case OMP_LIST_LINEAR: type = "LINEAR"; break;
-	  case OMP_LIST_DEPEND: type = "DEPEND"; break;
-	  case OMP_LIST_MAP: type = "MAP"; break;
-	  case OMP_LIST_TO: type = "TO"; break;
-	  case OMP_LIST_FROM: type = "FROM"; break;
-	  case OMP_LIST_REDUCTION:
-	  case OMP_LIST_REDUCTION_INSCAN:
-	  case OMP_LIST_REDUCTION_TASK: type = "REDUCTION"; break;
-	  case OMP_LIST_IN_REDUCTION: type = "IN_REDUCTION"; break;
-	  case OMP_LIST_TASK_REDUCTION: type = "TASK_REDUCTION"; break;
-	  case OMP_LIST_DEVICE_RESIDENT: type = "DEVICE_RESIDENT"; break;
-	  case OMP_LIST_LINK: type = "LINK"; break;
-	  case OMP_LIST_USE_DEVICE: type = "USE_DEVICE"; break;
-	  case OMP_LIST_CACHE: type = "CACHE"; break;
-	  case OMP_LIST_IS_DEVICE_PTR: type = "IS_DEVICE_PTR"; break;
-	  case OMP_LIST_USE_DEVICE_PTR: type = "USE_DEVICE_PTR"; break;
-	  case OMP_LIST_USE_DEVICE_ADDR: type = "USE_DEVICE_ADDR"; break;
-	  case OMP_LIST_NONTEMPORAL: type = "NONTEMPORAL"; break;
-	  default:
-	    gcc_unreachable ();
-	  }
+	const char *type = gfc_omp_get_clause_name (list->clause);
 	fprintf (dumpfile, " %s(", type);
-	if (list_type == OMP_LIST_REDUCTION_INSCAN)
+	if (list->clause == OMP_LIST_REDUCTION_INSCAN)
 	  fputs ("inscan, ", dumpfile);
-	if (list_type == OMP_LIST_REDUCTION_TASK)
+	if (list->clause == OMP_LIST_REDUCTION_TASK)
 	  fputs ("task, ", dumpfile);
-	show_omp_namelist (list_type, omp_clauses->lists[list_type]);
+	show_omp_namelist (list->clause, list->item);
 	fputc (')', dumpfile);
       }
   if (omp_clauses->safelen_expr)
@@ -1910,7 +1878,7 @@  show_omp_node (int level, gfc_code *c)
       if (c->ext.omp_namelist)
 	{
 	  fputs (" (", dumpfile);
-	  show_omp_namelist (OMP_LIST_NUM, c->ext.omp_namelist);
+	  show_omp_namelist (OMP_LIST_UNSET, c->ext.omp_namelist);
 	  fputc (')', dumpfile);
 	}
       return;
@@ -1958,11 +1926,12 @@  show_omp_node (int level, gfc_code *c)
   fprintf (dumpfile, "!$%s END %s", is_oacc ? "ACC" : "OMP", name);
   if (omp_clauses != NULL)
     {
-      if (omp_clauses->lists[OMP_LIST_COPYPRIVATE])
+      gfc_omp_namelist_item *list = gfc_omp_get_nm_list (omp_clauses,
+							 OMP_LIST_COPYPRIVATE);
+      if (list)
 	{
 	  fputs (" COPYPRIVATE(", dumpfile);
-	  show_omp_namelist (OMP_LIST_COPYPRIVATE,
-			     omp_clauses->lists[OMP_LIST_COPYPRIVATE]);
+	  show_omp_namelist (OMP_LIST_COPYPRIVATE, list);
 	  fputc (')', dumpfile);
 	}
       else if (omp_clauses->nowait)
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 83f6fd804b1..8629259d675 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -5578,10 +5578,8 @@  gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 
 	      if (co->ext.omp_clauses)
 		{
-		  gfc_omp_namelist *n;
-		  static int list_types[]
-		    = { OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND,
-			OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
+		  gfc_omp_namelist *list;
+		  gfc_omp_namelist_item *n;
 		  size_t idx;
 		  WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
 		  WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
@@ -5599,11 +5597,9 @@  gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 		  WALK_SUBEXPR (co->ext.omp_clauses->priority);
 		  for (idx = 0; idx < OMP_IF_LAST; idx++)
 		    WALK_SUBEXPR (co->ext.omp_clauses->if_exprs[idx]);
-		  for (idx = 0;
-		       idx < sizeof (list_types) / sizeof (list_types[0]);
-		       idx++)
-		    for (n = co->ext.omp_clauses->lists[list_types[idx]];
-			 n; n = n->next)
+		  for (list = co->ext.omp_clauses->lists;
+		       list; list = list->next)
+		    for (n = list->item; n; n = n->next)
 		      WALK_SUBEXPR (n->expr);
 		}
 	      break;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 6467985ea7f..69f231f688d 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1240,7 +1240,7 @@  enum gfc_omp_linear_op
 /* For use in OpenMP clauses in case we need extra information
    (aligned clause alignment, linear clause step, etc.).  */
 
-typedef struct gfc_omp_namelist
+typedef struct gfc_omp_namelist_item
 {
   struct gfc_symbol *sym;
   struct gfc_expr *expr;
@@ -1254,17 +1254,16 @@  typedef struct gfc_omp_namelist
       bool lastprivate_conditional;
     } u;
   struct gfc_omp_namelist_udr *udr;
-  struct gfc_omp_namelist *next;
+  struct gfc_omp_namelist_item *next;
   locus where;
 }
-gfc_omp_namelist;
+gfc_omp_namelist_item;
+#define gfc_get_omp_namelist_item() XCNEW (gfc_omp_namelist_item)
 
-#define gfc_get_omp_namelist() XCNEW (gfc_omp_namelist)
-
-enum
+enum omp_list_clauses
 {
-  OMP_LIST_FIRST,
-  OMP_LIST_PRIVATE = OMP_LIST_FIRST,
+  OMP_LIST_UNSET,
+  OMP_LIST_PRIVATE,
   OMP_LIST_FIRSTPRIVATE,
   OMP_LIST_LASTPRIVATE,
   OMP_LIST_COPYPRIVATE,
@@ -1289,8 +1288,7 @@  enum
   OMP_LIST_IS_DEVICE_PTR,
   OMP_LIST_USE_DEVICE_PTR,
   OMP_LIST_USE_DEVICE_ADDR,
-  OMP_LIST_NONTEMPORAL,
-  OMP_LIST_NUM
+  OMP_LIST_NONTEMPORAL
 };
 
 /* Because a symbol can belong to multiple namelists, they must be
@@ -1386,12 +1384,22 @@  enum gfc_omp_memorder
   OMP_MEMORDER_RELAXED
 };
 
+typedef struct gfc_omp_namelist
+{
+  enum omp_list_clauses clause;
+  gfc_omp_namelist_item *item;
+  struct gfc_omp_namelist *next;
+}
+gfc_omp_namelist;
+
+#define gfc_get_omp_namelist() XCNEW (gfc_omp_namelist)
+
 typedef struct gfc_omp_clauses
 {
   struct gfc_expr *if_expr;
   struct gfc_expr *final_expr;
   struct gfc_expr *num_threads;
-  gfc_omp_namelist *lists[OMP_LIST_NUM];
+  gfc_omp_namelist *lists;
   enum gfc_omp_sched_kind sched_kind;
   enum gfc_omp_device_type device_type;
   struct gfc_expr *chunk_size;
@@ -1434,7 +1442,6 @@  typedef struct gfc_omp_clauses
   unsigned par_auto:1, gang_static:1;
   unsigned if_present:1, finalize:1;
   locus loc;
-
 }
 gfc_omp_clauses;
 
@@ -2752,7 +2759,7 @@  typedef struct gfc_code
     gfc_oacc_declare *oacc_declare;
     gfc_omp_clauses *omp_clauses;
     const char *omp_name;
-    gfc_omp_namelist *omp_namelist;
+    gfc_omp_namelist_item *omp_namelist;
     bool omp_bool;
   }
   ext;		/* Points to additional structures required by statement */
@@ -3311,7 +3318,7 @@  void gfc_free_iterator (gfc_iterator *, int);
 void gfc_free_forall_iterator (gfc_forall_iterator *);
 void gfc_free_alloc_list (gfc_alloc *);
 void gfc_free_namelist (gfc_namelist *);
-void gfc_free_omp_namelist (gfc_omp_namelist *);
+void gfc_free_omp_namelist_item (gfc_omp_namelist_item *);
 void gfc_free_equiv (gfc_equiv *);
 void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *);
 void gfc_free_data (gfc_data *);
@@ -3325,6 +3332,7 @@  gfc_expr *gfc_get_parentheses (gfc_expr *);
 struct gfc_omp_saved_state { void *ptrs[2]; int ints[1]; };
 bool gfc_omp_requires_add_clause (gfc_omp_requires_kind, const char *,
 				  locus *, const char *);
+const char* gfc_omp_get_clause_name (enum omp_list_clauses clause);
 void gfc_check_omp_requires (gfc_namespace *, int);
 void gfc_free_omp_clauses (gfc_omp_clauses *);
 void gfc_free_oacc_declare_clauses (struct gfc_oacc_declare *);
@@ -3332,6 +3340,10 @@  void gfc_free_omp_declare_simd (gfc_omp_declare_simd *);
 void gfc_free_omp_declare_simd_list (gfc_omp_declare_simd *);
 void gfc_free_omp_udr (gfc_omp_udr *);
 gfc_omp_udr *gfc_omp_udr_find (gfc_symtree *, gfc_typespec *);
+gfc_omp_namelist_item** gfc_omp_get_nm_ref (gfc_omp_clauses *,
+					    enum omp_list_clauses);
+gfc_omp_namelist_item* gfc_omp_get_nm_list (gfc_omp_clauses *,
+					    enum omp_list_clauses);
 void gfc_resolve_omp_directive (gfc_code *, gfc_namespace *);
 void gfc_resolve_do_iterator (gfc_code *, gfc_symbol *, bool);
 void gfc_resolve_omp_local_vars (gfc_namespace *);
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index bee73e7b008..baacf28cb95 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -5467,9 +5467,9 @@  gfc_free_namelist (gfc_namelist *name)
 /* Free an OpenMP namelist structure.  */
 
 void
-gfc_free_omp_namelist (gfc_omp_namelist *name)
+gfc_free_omp_namelist_item (gfc_omp_namelist_item *name)
 {
-  gfc_omp_namelist *n;
+  gfc_omp_namelist_item *n;
 
   for (; name; name = n)
     {
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 4c6ff22d5c1..1091228d3e5 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -4357,7 +4357,7 @@  mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
       write_atom (ATOM_NAME, "OMP_DECLARE_SIMD");
       if (ods->clauses)
 	{
-	  gfc_omp_namelist *n;
+	  gfc_omp_namelist_item *n;
 
 	  if (ods->clauses->inbranch)
 	    mio_name (0, omp_declare_simd_clauses);
@@ -4368,12 +4368,14 @@  mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
 	      mio_name (2, omp_declare_simd_clauses);
 	      mio_expr (&ods->clauses->simdlen_expr);
 	    }
-	  for (n = ods->clauses->lists[OMP_LIST_UNIFORM]; n; n = n->next)
+	  n = gfc_omp_get_nm_list (ods->clauses, OMP_LIST_UNIFORM);
+	  for (; n; n = n->next)
 	    {
 	      mio_name (3, omp_declare_simd_clauses);
 	      mio_symbol_ref (&n->sym);
 	    }
-	  for (n = ods->clauses->lists[OMP_LIST_LINEAR]; n; n = n->next)
+	  n = gfc_omp_get_nm_list (ods->clauses, OMP_LIST_LINEAR);
+	  for (; n; n = n->next)
 	    {
 	      if (n->u.linear_op == OMP_LINEAR_DEFAULT)
 		mio_name (4, omp_declare_simd_clauses);
@@ -4382,7 +4384,8 @@  mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
 	      mio_symbol_ref (&n->sym);
 	      mio_expr (&n->expr);
 	    }
-	  for (n = ods->clauses->lists[OMP_LIST_ALIGNED]; n; n = n->next)
+	  n = gfc_omp_get_nm_list (ods->clauses, OMP_LIST_ALIGNED);
+	  for (; n; n = n->next)
 	    {
 	      mio_name (5, omp_declare_simd_clauses);
 	      mio_symbol_ref (&n->sym);
@@ -4392,7 +4395,7 @@  mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
     }
   else
     {
-      gfc_omp_namelist **ptrs[3] = { NULL, NULL, NULL };
+      gfc_omp_namelist_item **ptrs[3] = { NULL, NULL, NULL };
 
       require_atom (ATOM_NAME);
       *odsp = ods = gfc_get_omp_declare_simd ();
@@ -4401,13 +4404,19 @@  mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
       if (peek_atom () == ATOM_NAME)
 	{
 	  ods->clauses = gfc_get_omp_clauses ();
-	  ptrs[0] = &ods->clauses->lists[OMP_LIST_UNIFORM];
-	  ptrs[1] = &ods->clauses->lists[OMP_LIST_LINEAR];
-	  ptrs[2] = &ods->clauses->lists[OMP_LIST_ALIGNED];
+	  ods->clauses->lists = gfc_get_omp_namelist ();
+	  ods->clauses->lists->next = gfc_get_omp_namelist ();
+	  ods->clauses->lists->next->next = gfc_get_omp_namelist ();
+	  ods->clauses->lists->clause = OMP_LIST_UNIFORM;
+	  ods->clauses->lists->next->clause = OMP_LIST_UNIFORM;
+	  ods->clauses->lists->next->next->clause = OMP_LIST_UNIFORM;
+	  ptrs[0] = &ods->clauses->lists->item;
+	  ptrs[1] = &ods->clauses->lists->next->item;
+	  ptrs[2] = &ods->clauses->lists->next->next->item;
 	}
       while (peek_atom () == ATOM_NAME)
 	{
-	  gfc_omp_namelist *n;
+	  gfc_omp_namelist_item *n;
 	  int t = mio_name (0, omp_declare_simd_clauses);
 
 	  switch (t)
@@ -4418,7 +4427,7 @@  mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
 	    case 3:
 	    case 4:
 	    case 5:
-	      *ptrs[t - 3] = n = gfc_get_omp_namelist ();
+	      *ptrs[t - 3] = n = gfc_get_omp_namelist_item ();
 	    finish_namelist:
 	      n->where = gfc_current_locus;
 	      ptrs[t - 3] = &n->next;
@@ -4429,7 +4438,7 @@  mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
 	    case 33:
 	    case 34:
 	    case 35:
-	      *ptrs[1] = n = gfc_get_omp_namelist ();
+	      *ptrs[1] = n = gfc_get_omp_namelist_item ();
 	      n->u.linear_op = (enum gfc_omp_linear_op) (t - 32);
 	      t = 4;
 	      goto finish_namelist;
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 68d0b65ff87..19ccdd52ce9 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -101,8 +101,13 @@  gfc_free_omp_clauses (gfc_omp_clauses *c)
   gfc_free_expr (c->num_gangs_expr);
   gfc_free_expr (c->num_workers_expr);
   gfc_free_expr (c->vector_length_expr);
-  for (i = 0; i < OMP_LIST_NUM; i++)
-    gfc_free_omp_namelist (c->lists[i]);
+  for (gfc_omp_namelist *list = c->lists; list; )
+    {
+      gfc_omp_namelist *next = list->next;
+      gfc_free_omp_namelist_item (list->item);
+      free (list);
+      list = next;
+    }
   gfc_free_expr_list (c->wait_list);
   gfc_free_expr_list (c->tile_list);
   free (CONST_CAST (char *, c->critical_name));
@@ -230,13 +235,13 @@  gfc_find_omp_udr (gfc_namespace *ns, const char *name, gfc_typespec *ts)
 /* Match a variable/common block list and construct a namelist from it.  */
 
 static match
-gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list,
+gfc_match_omp_variable_list (const char *str, gfc_omp_namelist_item **list,
 			     bool allow_common, bool *end_colon = NULL,
-			     gfc_omp_namelist ***headp = NULL,
+			     gfc_omp_namelist_item ***headp = NULL,
 			     bool allow_sections = false,
 			     bool allow_derived = false)
 {
-  gfc_omp_namelist *head, *tail, *p;
+  gfc_omp_namelist_item *head, *tail, *p;
   locus old_loc, cur_loc;
   char n[GFC_MAX_SYMBOL_LEN+1];
   gfc_symbol *sym;
@@ -281,7 +286,7 @@  gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list,
 		}
 	    }
 	  gfc_set_sym_referenced (sym);
-	  p = gfc_get_omp_namelist ();
+	  p = gfc_get_omp_namelist_item ();
 	  if (head == NULL)
 	    head = tail = p;
 	  else
@@ -317,7 +322,7 @@  gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list,
       for (sym = st->n.common->head; sym; sym = sym->common_next)
 	{
 	  gfc_set_sym_referenced (sym);
-	  p = gfc_get_omp_namelist ();
+	  p = gfc_get_omp_namelist_item ();
 	  if (head == NULL)
 	    head = tail = p;
 	  else
@@ -353,7 +358,7 @@  syntax:
   gfc_error ("Syntax error in OpenMP variable list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head);
+  gfc_free_omp_namelist_item (head);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -362,9 +367,9 @@  cleanup:
    from it.  */
 
 static match
-gfc_match_omp_to_link (const char *str, gfc_omp_namelist **list)
+gfc_match_omp_to_link (const char *str, gfc_omp_namelist_item **list)
 {
-  gfc_omp_namelist *head, *tail, *p;
+  gfc_omp_namelist_item *head, *tail, *p;
   locus old_loc, cur_loc;
   char n[GFC_MAX_SYMBOL_LEN+1];
   gfc_symbol *sym;
@@ -386,7 +391,7 @@  gfc_match_omp_to_link (const char *str, gfc_omp_namelist **list)
       switch (m)
 	{
 	case MATCH_YES:
-	  p = gfc_get_omp_namelist ();
+	  p = gfc_get_omp_namelist_item ();
 	  if (head == NULL)
 	    head = tail = p;
 	  else
@@ -415,7 +420,7 @@  gfc_match_omp_to_link (const char *str, gfc_omp_namelist **list)
 	  gfc_error ("COMMON block /%s/ not found at %C", n);
 	  goto cleanup;
 	}
-      p = gfc_get_omp_namelist ();
+      p = gfc_get_omp_namelist_item ();
       if (head == NULL)
 	head = tail = p;
       else
@@ -443,7 +448,7 @@  syntax:
   gfc_error ("Syntax error in OpenMP variable list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head);
+  gfc_free_omp_namelist_item (head);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -451,9 +456,9 @@  cleanup:
 /* Match depend(sink : ...) construct a namelist from it.  */
 
 static match
-gfc_match_omp_depend_sink (gfc_omp_namelist **list)
+gfc_match_omp_depend_sink (gfc_omp_namelist_item **list)
 {
-  gfc_omp_namelist *head, *tail, *p;
+  gfc_omp_namelist_item *head, *tail, *p;
   locus old_loc, cur_loc;
   gfc_symbol *sym;
 
@@ -468,7 +473,7 @@  gfc_match_omp_depend_sink (gfc_omp_namelist **list)
 	{
 	case MATCH_YES:
 	  gfc_set_sym_referenced (sym);
-	  p = gfc_get_omp_namelist ();
+	  p = gfc_get_omp_namelist_item ();
 	  if (head == NULL)
 	    {
 	      head = tail = p;
@@ -517,7 +522,7 @@  syntax:
   gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head);
+  gfc_free_omp_namelist_item (head);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -649,10 +654,10 @@  match_oacc_clause_gwv (gfc_omp_clauses *cp, unsigned gwv)
 }
 
 static match
-gfc_match_oacc_clause_link (const char *str, gfc_omp_namelist **list)
+gfc_match_oacc_clause_link (const char *str, gfc_omp_namelist_item **list)
 {
-  gfc_omp_namelist *head = NULL;
-  gfc_omp_namelist *tail, *p;
+  gfc_omp_namelist_item *head = NULL;
+  gfc_omp_namelist_item *tail, *p;
   locus old_loc;
   char n[GFC_MAX_SYMBOL_LEN+1];
   gfc_symbol *sym;
@@ -679,7 +684,7 @@  gfc_match_oacc_clause_link (const char *str, gfc_omp_namelist **list)
 	      goto cleanup;
 	    }
 	  gfc_set_sym_referenced (sym);
-	  p = gfc_get_omp_namelist ();
+	  p = gfc_get_omp_namelist_item ();
 	  if (head == NULL)
 	    head = tail = p;
 	  else
@@ -714,7 +719,7 @@  gfc_match_oacc_clause_link (const char *str, gfc_omp_namelist **list)
       for (sym = st->n.common->head; sym; sym = sym->common_next)
 	{
 	  gfc_set_sym_referenced (sym);
-	  p = gfc_get_omp_namelist ();
+	  p = gfc_get_omp_namelist_item ();
 	  if (head == NULL)
 	    head = tail = p;
 	  else
@@ -944,15 +949,15 @@  omp_inv_mask::omp_inv_mask (const omp_mask &m) : omp_mask (m)
    mapping.  */
 
 static bool
-gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
+gfc_match_omp_map_clause (gfc_omp_namelist_item **list, gfc_omp_map_op map_op,
 			  bool allow_common, bool allow_derived)
 {
-  gfc_omp_namelist **head = NULL;
+  gfc_omp_namelist_item **head = NULL;
   if (gfc_match_omp_variable_list ("", list, allow_common, NULL, &head, true,
 				   allow_derived)
       == MATCH_YES)
     {
-      gfc_omp_namelist *n;
+      gfc_omp_namelist_item *n;
       for (n = *head; n; n = n->next)
 	n->u.map_op = map_op;
       return true;
@@ -961,6 +966,79 @@  gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
   return false;
 }
 
+
+const char*
+gfc_omp_get_clause_name (enum omp_list_clauses clause)
+{
+  switch (clause)
+    {
+    case OMP_LIST_PRIVATE: return "PRIVATE";
+    case OMP_LIST_FIRSTPRIVATE: return "FIRSTPRIVATE";
+    case OMP_LIST_LASTPRIVATE: return "LASTPRIVATE";
+    case OMP_LIST_COPYPRIVATE: return "COPYPRIVATE";
+    case OMP_LIST_SHARED: return "SHARED";
+    case OMP_LIST_COPYIN: return "COPYIN";
+    case OMP_LIST_UNIFORM: return "UNIFORM";
+    case OMP_LIST_ALIGNED: return "ALIGNED";
+    case OMP_LIST_LINEAR: return "LINEAR";
+    case OMP_LIST_DEPEND: return "DEPEND";
+    case OMP_LIST_MAP: return "MAP";
+    case OMP_LIST_TO: return "TO";
+    case OMP_LIST_FROM: return "FROM";
+    case OMP_LIST_REDUCTION:
+    case OMP_LIST_REDUCTION_INSCAN:
+    case OMP_LIST_REDUCTION_TASK: return "REDUCTION";
+    case OMP_LIST_IN_REDUCTION: return "IN_REDUCTION";
+    case OMP_LIST_TASK_REDUCTION: return "TASK_REDUCTION";
+    case OMP_LIST_DEVICE_RESIDENT: return "DEVICE_RESIDENT";
+    case OMP_LIST_LINK: return "LINK";
+    case OMP_LIST_USE_DEVICE: return "USE_DEVICE";
+    case OMP_LIST_CACHE: return "CACHE";
+    case OMP_LIST_IS_DEVICE_PTR: return "IS_DEVICE_PTR";
+    case OMP_LIST_USE_DEVICE_PTR: return "USE_DEVICE_PTR";
+    case OMP_LIST_USE_DEVICE_ADDR: return "USE_DEVICE_ADDR";
+    case OMP_LIST_NONTEMPORAL: return "NONTEMPORAL";
+    case OMP_LIST_UNSET: break;
+    }
+  gcc_unreachable ();
+  return "";
+}
+
+
+gfc_omp_namelist_item **
+gfc_omp_get_nm_ref (gfc_omp_clauses *clauses, enum omp_list_clauses clause)
+{
+  gfc_omp_namelist *found, *last = NULL;
+  for (found = clauses->lists; found; found = found->next)
+    {
+      if (found->clause == clause)
+	break;
+      last = found;
+    }
+  if (!found)
+    {
+      found = gfc_get_omp_namelist ();
+      found->clause = clause;
+      if (last)
+	last->next = found;
+      else
+        clauses->lists = found;
+    }
+  return &found->item;
+}
+
+
+gfc_omp_namelist_item *
+gfc_omp_get_nm_list (gfc_omp_clauses *clauses, enum omp_list_clauses clause)
+{
+  gfc_omp_namelist *found;
+  for (found = clauses->lists; found; found = found->next)
+    if (found->clause == clause)
+      break;
+  return found ? found->item : NULL;
+}
+
+
 /* reduction ( reduction-modifier, reduction-operator : variable-list )
    in_reduction ( reduction-operator : variable-list )
    task_reduction ( reduction-operator : variable-list )  */
@@ -977,31 +1055,31 @@  gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
     return MATCH_NO;
 
   locus old_loc = gfc_current_locus;
-  int list_idx = 0;
+  enum omp_list_clauses subclause = OMP_LIST_UNSET;
 
   if (pc == 'r' && !openacc)
     {
       if (gfc_match ("inscan") == MATCH_YES)
-	list_idx = OMP_LIST_REDUCTION_INSCAN;
+	subclause = OMP_LIST_REDUCTION_INSCAN;
       else if (gfc_match ("task") == MATCH_YES)
-	list_idx = OMP_LIST_REDUCTION_TASK;
+	subclause = OMP_LIST_REDUCTION_TASK;
       else if (gfc_match ("default") == MATCH_YES)
-	list_idx = OMP_LIST_REDUCTION;
-      if (list_idx != 0 && gfc_match (", ") != MATCH_YES)
+	subclause = OMP_LIST_REDUCTION;
+      if (subclause != OMP_LIST_UNSET && gfc_match (", ") != MATCH_YES)
 	{
 	  gfc_error ("Comma expected at %C");
 	  gfc_current_locus = old_loc;
 	  return MATCH_NO;
 	}
-      if (list_idx == 0)
-	list_idx = OMP_LIST_REDUCTION;
+      if (subclause == OMP_LIST_UNSET)
+	subclause = OMP_LIST_REDUCTION;
     }
   else if (pc == 'i')
-    list_idx = OMP_LIST_IN_REDUCTION;
+    subclause = OMP_LIST_IN_REDUCTION;
   else if (pc == 't')
-    list_idx = OMP_LIST_TASK_REDUCTION;
+    subclause = OMP_LIST_TASK_REDUCTION;
   else
-    list_idx = OMP_LIST_REDUCTION;
+    subclause = OMP_LIST_REDUCTION;
 
   gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
   char buffer[GFC_MAX_SYMBOL_LEN + 3];
@@ -1086,24 +1164,25 @@  gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
     buffer[0] = '\0';
   gfc_omp_udr *udr = (buffer[0] ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL)
 				: NULL);
-  gfc_omp_namelist **head = NULL;
+  gfc_omp_namelist_item **head = NULL;
   if (rop == OMP_REDUCTION_NONE && udr)
     rop = OMP_REDUCTION_USER;
 
-  if (gfc_match_omp_variable_list (" :", &c->lists[list_idx], false, NULL,
-				   &head, openacc, allow_derived) != MATCH_YES)
+  gfc_omp_namelist_item **list = gfc_omp_get_nm_ref (c, subclause);
+  if (gfc_match_omp_variable_list (" :", list, false, NULL, &head, openacc,
+				   allow_derived) != MATCH_YES)
     {
       gfc_current_locus = old_loc;
       return MATCH_NO;
     }
-  gfc_omp_namelist *n;
+  gfc_omp_namelist_item *n;
   if (rop == OMP_REDUCTION_NONE)
     {
       n = *head;
       *head = NULL;
       gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
 		     buffer, &old_loc);
-      gfc_free_omp_namelist (n);
+      gfc_free_omp_namelist_item (n);
     }
   else
     for (n = *head; n; n = n->next)
@@ -1148,7 +1227,7 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
       first = false;
       gfc_gobble_whitespace ();
       bool end_colon;
-      gfc_omp_namelist **head;
+      gfc_omp_namelist_item **head;
       old_loc = gfc_current_locus;
       char pc = gfc_peek_ascii_char ();
       switch (pc)
@@ -1157,17 +1236,16 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	  end_colon = false;
 	  head = NULL;
 	  if ((mask & OMP_CLAUSE_ALIGNED)
-	      && gfc_match_omp_variable_list ("aligned (",
-					      &c->lists[OMP_LIST_ALIGNED],
-					      false, &end_colon,
-					      &head) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		   "aligned (", gfc_omp_get_nm_ref (c, OMP_LIST_ALIGNED),
+		   false, &end_colon, &head) == MATCH_YES)
 	    {
 	      gfc_expr *alignment = NULL;
-	      gfc_omp_namelist *n;
+	      gfc_omp_namelist_item *n;
 
 	      if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES)
 		{
-		  gfc_free_omp_namelist (*head);
+		  gfc_free_omp_namelist_item (*head);
 		  gfc_current_locus = old_loc;
 		  *head = NULL;
 		  break;
@@ -1227,9 +1305,9 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  if ((mask & OMP_CLAUSE_ATTACH)
 	      && gfc_match ("attach ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_ATTACH, false,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_ATTACH, false, allow_derived))
 	    continue;
 	  break;
 	case 'c':
@@ -1265,39 +1343,43 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  if ((mask & OMP_CLAUSE_COPY)
 	      && gfc_match ("copy ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_TOFROM, true,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_TOFROM, true, allow_derived))
 	    continue;
 	  if (mask & OMP_CLAUSE_COPYIN)
 	    {
 	      if (openacc)
 		{
 		  if (gfc_match ("copyin ( ") == MATCH_YES
-		      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-						   OMP_MAP_TO, true,
-						   allow_derived))
+		      && gfc_match_omp_map_clause (
+			   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+			   OMP_MAP_TO, true, allow_derived))
 		    continue;
 		}
-	      else if (gfc_match_omp_variable_list ("copyin (",
-						    &c->lists[OMP_LIST_COPYIN],
-						    true) == MATCH_YES)
+	      else if (gfc_match_omp_variable_list (
+			 "copyin (",
+			 gfc_omp_get_nm_ref (c, OMP_LIST_COPYIN), true)
+		       == MATCH_YES)
 		continue;
 	    }
 	  if ((mask & OMP_CLAUSE_COPYOUT)
 	      && gfc_match ("copyout ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FROM, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_FROM, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_COPYPRIVATE)
-	      && gfc_match_omp_variable_list ("copyprivate (",
-					      &c->lists[OMP_LIST_COPYPRIVATE],
-					      true) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		   "copyprivate (",
+		   gfc_omp_get_nm_ref (c, OMP_LIST_COPYPRIVATE), true)
+		 == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_CREATE)
 	      && gfc_match ("create ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_ALLOC, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_ALLOC, true, allow_derived))
 	    continue;
 	  break;
 	case 'd':
@@ -1332,9 +1414,9 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  if ((mask & OMP_CLAUSE_DELETE)
 	      && gfc_match ("delete ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_RELEASE, true,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_RELEASE, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_DEPEND)
 	      && gfc_match ("depend ( ") == MATCH_YES)
@@ -1355,8 +1437,8 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		}
 	      else if (gfc_match ("sink : ") == MATCH_YES)
 		{
-		  if (gfc_match_omp_depend_sink (&c->lists[OMP_LIST_DEPEND])
-		      == MATCH_YES)
+		  if (gfc_match_omp_depend_sink (
+			gfc_omp_get_nm_ref (c, OMP_LIST_DEPEND)) == MATCH_YES)
 		    continue;
 		  m = MATCH_NO;
 		}
@@ -1364,12 +1446,11 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		m = MATCH_NO;
 	      head = NULL;
 	      if (m == MATCH_YES
-		  && gfc_match_omp_variable_list (" : ",
-						  &c->lists[OMP_LIST_DEPEND],
-						  false, NULL, &head,
-						  true) == MATCH_YES)
+		  && gfc_match_omp_variable_list (
+			" : ", gfc_omp_get_nm_ref (c, OMP_LIST_DEPEND),
+			false, NULL, &head, true) == MATCH_YES)
 		{
-		  gfc_omp_namelist *n;
+		  gfc_omp_namelist_item *n;
 		  for (n = *head; n; n = n->next)
 		    n->u.depend_op = depend_op;
 		  continue;
@@ -1379,9 +1460,9 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  if ((mask & OMP_CLAUSE_DETACH)
 	      && gfc_match ("detach ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_DETACH, false,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_DETACH, false, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_DEVICE)
 	      && !openacc
@@ -1391,15 +1472,15 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	  if ((mask & OMP_CLAUSE_DEVICE)
 	      && openacc
 	      && gfc_match ("device ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FORCE_TO, true,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_FORCE_TO, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_DEVICEPTR)
 	      && gfc_match ("deviceptr ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FORCE_DEVICEPTR, false,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_FORCE_DEVICEPTR, false, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_DEVICE_TYPE)
 	      && gfc_match ("device_type ( ") == MATCH_YES)
@@ -1422,7 +1503,8 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	  if ((mask & OMP_CLAUSE_DEVICE_RESIDENT)
 	      && gfc_match_omp_variable_list
 		   ("device_resident (",
-		    &c->lists[OMP_LIST_DEVICE_RESIDENT], true) == MATCH_YES)
+		    gfc_omp_get_nm_ref (c, OMP_LIST_DEVICE_RESIDENT), true)
+		 == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_DIST_SCHEDULE)
 	      && c->dist_sched_kind == OMP_SCHED_NONE
@@ -1456,14 +1538,15 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
-	      && gfc_match_omp_variable_list ("firstprivate (",
-					      &c->lists[OMP_LIST_FIRSTPRIVATE],
-					      true) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		    "firstprivate (",
+		    gfc_omp_get_nm_ref (c, OMP_LIST_FIRSTPRIVATE), true)
+		 == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_FROM)
-	      && gfc_match_omp_variable_list ("from (",
-					      &c->lists[OMP_LIST_FROM], false,
-					      NULL, &head, true) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		    "from (", gfc_omp_get_nm_ref (c, OMP_LIST_FROM),
+		    false, NULL, &head, true) == MATCH_YES)
 	    continue;
 	  break;
 	case 'g':
@@ -1494,9 +1577,9 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    continue;
 	  if ((mask & OMP_CLAUSE_HOST_SELF)
 	      && gfc_match ("host ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FORCE_FROM, true,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		    gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		    OMP_MAP_FORCE_FROM, true, allow_derived))
 	    continue;
 	  break;
 	case 'i':
@@ -1561,7 +1644,8 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	  if ((mask & OMP_CLAUSE_IS_DEVICE_PTR)
 	      && gfc_match_omp_variable_list
 		   ("is_device_ptr (",
-		    &c->lists[OMP_LIST_IS_DEVICE_PTR], false) == MATCH_YES)
+		    gfc_omp_get_nm_ref (c, OMP_LIST_IS_DEVICE_PTR), false)
+		 == MATCH_YES)
 	    continue;
 	  break;
 	case 'l':
@@ -1570,11 +1654,11 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      bool conditional = gfc_match ("conditional : ") == MATCH_YES;
 	      head = NULL;
-	      if (gfc_match_omp_variable_list ("",
-					       &c->lists[OMP_LIST_LASTPRIVATE],
-					       false, NULL, &head) == MATCH_YES)
+	      if (gfc_match_omp_variable_list (
+		    "", gfc_omp_get_nm_ref (c, OMP_LIST_LASTPRIVATE),
+		    false, NULL, &head) == MATCH_YES)
 		{
-		  gfc_omp_namelist *n;
+		  gfc_omp_namelist_item *n;
 		  for (n = *head; n; n = n->next)
 		    n->u.lastprivate_conditional = conditional;
 		  continue;
@@ -1590,25 +1674,21 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      gfc_omp_linear_op linear_op = OMP_LINEAR_DEFAULT;
 	      gfc_expr *step = NULL;
 
-	      if (gfc_match_omp_variable_list (" ref (",
-					       &c->lists[OMP_LIST_LINEAR],
-					       false, NULL, &head)
-		  == MATCH_YES)
+	      if (gfc_match_omp_variable_list (
+		    " ref (", gfc_omp_get_nm_ref (c, OMP_LIST_LINEAR),
+		    false, NULL, &head) == MATCH_YES)
 		linear_op = OMP_LINEAR_REF;
-	      else if (gfc_match_omp_variable_list (" val (",
-						    &c->lists[OMP_LIST_LINEAR],
-						    false, NULL, &head)
-		       == MATCH_YES)
+	      else if (gfc_match_omp_variable_list (
+		       " val (", gfc_omp_get_nm_ref (c, OMP_LIST_LINEAR),
+		       false, NULL, &head) == MATCH_YES)
 		linear_op = OMP_LINEAR_VAL;
-	      else if (gfc_match_omp_variable_list (" uval (",
-						    &c->lists[OMP_LIST_LINEAR],
-						    false, NULL, &head)
-		       == MATCH_YES)
+	      else if (gfc_match_omp_variable_list (
+		       " uval (", gfc_omp_get_nm_ref (c, OMP_LIST_LINEAR),
+		       false, NULL, &head) == MATCH_YES)
 		linear_op = OMP_LINEAR_UVAL;
-	      else if (gfc_match_omp_variable_list ("",
-						    &c->lists[OMP_LIST_LINEAR],
-						    false, &end_colon, &head)
-		       == MATCH_YES)
+	      else if (gfc_match_omp_variable_list (
+		       "", gfc_omp_get_nm_ref (c, OMP_LIST_LINEAR),
+		       false, &end_colon, &head) == MATCH_YES)
 		linear_op = OMP_LINEAR_DEFAULT;
 	      else
 		{
@@ -1621,7 +1701,7 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		    end_colon = true;
 		  else if (gfc_match (" )") != MATCH_YES)
 		    {
-		      gfc_free_omp_namelist (*head);
+		      gfc_free_omp_namelist_item (*head);
 		      gfc_current_locus = old_loc;
 		      *head = NULL;
 		      break;
@@ -1629,7 +1709,7 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		}
 	      if (end_colon && gfc_match (" %e )", &step) != MATCH_YES)
 		{
-		  gfc_free_omp_namelist (*head);
+		  gfc_free_omp_namelist_item (*head);
 		  gfc_current_locus = old_loc;
 		  *head = NULL;
 		  break;
@@ -1643,20 +1723,20 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		}
 	      (*head)->expr = step;
 	      if (linear_op != OMP_LINEAR_DEFAULT)
-		for (gfc_omp_namelist *n = *head; n; n = n->next)
+		for (gfc_omp_namelist_item *n = *head; n; n = n->next)
 		  n->u.linear_op = linear_op;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_LINK)
 	      && openacc
-	      && (gfc_match_oacc_clause_link ("link (",
-					      &c->lists[OMP_LIST_LINK])
+	      && (gfc_match_oacc_clause_link (
+		    "link (", gfc_omp_get_nm_ref (c, OMP_LIST_LINK))
 		  == MATCH_YES))
 	    continue;
 	  else if ((mask & OMP_CLAUSE_LINK)
 		   && !openacc
-		   && (gfc_match_omp_to_link ("link (",
-					      &c->lists[OMP_LIST_LINK])
+		   && (gfc_match_omp_to_link (
+		         "link (", gfc_omp_get_nm_ref (c, OMP_LIST_LINK))
 		       == MATCH_YES))
 	    continue;
 	  break;
@@ -1687,11 +1767,11 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		  always = false;
 		}
 	      head = NULL;
-	      if (gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_MAP],
-					       false, NULL, &head,
-					       true, true) == MATCH_YES)
+	      if (gfc_match_omp_variable_list (
+		    "", gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		    false, NULL, &head, true, true) == MATCH_YES)
 		{
-		  gfc_omp_namelist *n;
+		  gfc_omp_namelist_item *n;
 		  for (n = *head; n; n = n->next)
 		    n->u.map_op = map_op;
 		  continue;
@@ -1709,9 +1789,9 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	case 'n':
 	  if ((mask & OMP_CLAUSE_NO_CREATE)
 	      && gfc_match ("no_create ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_IF_PRESENT, true,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_IF_PRESENT, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_NOGROUP)
 	      && !c->nogroup
@@ -1721,9 +1801,10 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_NOTEMPORAL)
-	      && gfc_match_omp_variable_list ("nontemporal (",
-					      &c->lists[OMP_LIST_NONTEMPORAL],
-					      true) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		   "nontemporal (",
+		   gfc_omp_get_nm_ref (c, OMP_LIST_NONTEMPORAL), true)
+		 == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_NOTINBRANCH)
 	      && !c->notinbranch
@@ -1803,59 +1884,66 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	case 'p':
 	  if ((mask & OMP_CLAUSE_COPY)
 	      && gfc_match ("pcopy ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_TOFROM, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_TOFROM, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_COPYIN)
 	      && gfc_match ("pcopyin ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_TO, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_TO, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_COPYOUT)
 	      && gfc_match ("pcopyout ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FROM, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_FROM, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_CREATE)
 	      && gfc_match ("pcreate ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_ALLOC, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_ALLOC, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_PRESENT)
 	      && gfc_match ("present ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FORCE_PRESENT, false,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_FORCE_PRESENT, false, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_COPY)
 	      && gfc_match ("present_or_copy ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_TOFROM, true,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_TOFROM, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_COPYIN)
 	      && gfc_match ("present_or_copyin ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_TO, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_TO, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_COPYOUT)
 	      && gfc_match ("present_or_copyout ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FROM, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_FROM, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_CREATE)
 	      && gfc_match ("present_or_create ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_ALLOC, true, allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_ALLOC, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_PRIORITY)
 	      && c->priority == NULL
 	      && gfc_match ("priority ( %e )", &c->priority) == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_PRIVATE)
-	      && gfc_match_omp_variable_list ("private (",
-					      &c->lists[OMP_LIST_PRIVATE],
-					      true) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		   "private (", gfc_omp_get_nm_ref (c, OMP_LIST_PRIVATE),
+		   true) == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_PROC_BIND)
 	      && c->proc_bind == OMP_PROC_BIND_UNKNOWN)
@@ -1987,9 +2075,9 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  if ((mask & OMP_CLAUSE_HOST_SELF)
 	      && gfc_match ("self ( ") == MATCH_YES
-	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
-					   OMP_MAP_FORCE_FROM, true,
-					   allow_derived))
+	      && gfc_match_omp_map_clause (
+		   gfc_omp_get_nm_ref (c, OMP_LIST_MAP),
+		   OMP_MAP_FORCE_FROM, true, allow_derived))
 	    continue;
 	  if ((mask & OMP_CLAUSE_SEQ)
 	      && !c->seq
@@ -2008,9 +2096,9 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_SHARED)
-	      && gfc_match_omp_variable_list ("shared (",
-					      &c->lists[OMP_LIST_SHARED],
-					      true) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		   "shared (", gfc_omp_get_nm_ref (c, OMP_LIST_SHARED), true)
+		 == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_SIMDLEN)
 	      && c->simdlen_expr == NULL
@@ -2048,21 +2136,22 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    continue;
 	  if ((mask & OMP_CLAUSE_TO) && (mask & OMP_CLAUSE_LINK))
 	    {
-	      if (gfc_match_omp_to_link ("to (", &c->lists[OMP_LIST_TO])
+	      if (gfc_match_omp_to_link (
+		    "to (", gfc_omp_get_nm_ref (c, OMP_LIST_TO))
 		  == MATCH_YES)
 		continue;
 	    }
 	  else if ((mask & OMP_CLAUSE_TO)
-	      && gfc_match_omp_variable_list ("to (",
-					      &c->lists[OMP_LIST_TO], false,
-					      NULL, &head, true) == MATCH_YES)
+		   && gfc_match_omp_variable_list (
+			"to (", gfc_omp_get_nm_ref (c, OMP_LIST_TO),
+			false, NULL, &head, true) == MATCH_YES)
 	    continue;
 	  break;
 	case 'u':
 	  if ((mask & OMP_CLAUSE_UNIFORM)
-	      && gfc_match_omp_variable_list ("uniform (",
-					      &c->lists[OMP_LIST_UNIFORM],
-					      false) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		   "uniform (", gfc_omp_get_nm_ref (c, OMP_LIST_UNIFORM), false)
+		 == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_UNTIED)
 	      && !c->untied
@@ -2080,19 +2169,22 @@  gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_USE_DEVICE)
-	      && gfc_match_omp_variable_list ("use_device (",
-					      &c->lists[OMP_LIST_USE_DEVICE],
-					      true) == MATCH_YES)
+	      && gfc_match_omp_variable_list (
+		   "use_device (",
+		   gfc_omp_get_nm_ref (c, OMP_LIST_USE_DEVICE), true)
+		 == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_USE_DEVICE_PTR)
 	      && gfc_match_omp_variable_list
 		   ("use_device_ptr (",
-		    &c->lists[OMP_LIST_USE_DEVICE_PTR], false) == MATCH_YES)
+		    gfc_omp_get_nm_ref (c, OMP_LIST_USE_DEVICE_PTR),
+		    false) == MATCH_YES)
 	    continue;
 	  if ((mask & OMP_CLAUSE_USE_DEVICE_ADDR)
 	      && gfc_match_omp_variable_list
 		   ("use_device_addr (",
-		    &c->lists[OMP_LIST_USE_DEVICE_ADDR], false) == MATCH_YES)
+		    gfc_omp_get_nm_ref (c, OMP_LIST_USE_DEVICE_ADDR),
+		    false) == MATCH_YES)
 	    continue;
 	  break;
 	case 'v':
@@ -2324,7 +2416,7 @@  match
 gfc_match_oacc_declare (void)
 {
   gfc_omp_clauses *c;
-  gfc_omp_namelist *n;
+  gfc_omp_namelist_item *n;
   gfc_namespace *ns = gfc_current_ns;
   gfc_oacc_declare *new_oc;
   bool module_var = false;
@@ -2334,13 +2426,16 @@  gfc_match_oacc_declare (void)
       != MATCH_YES)
     return MATCH_ERROR;
 
-  for (n = c->lists[OMP_LIST_DEVICE_RESIDENT]; n != NULL; n = n->next)
+  n = gfc_omp_get_nm_list (c, OMP_LIST_DEVICE_RESIDENT);
+  for (; n != NULL; n = n->next)
     n->sym->attr.oacc_declare_device_resident = 1;
 
-  for (n = c->lists[OMP_LIST_LINK]; n != NULL; n = n->next)
+  n = gfc_omp_get_nm_list (c, OMP_LIST_LINK);
+  for (; n != NULL; n = n->next)
     n->sym->attr.oacc_declare_link = 1;
 
-  for (n = c->lists[OMP_LIST_MAP]; n != NULL; n = n->next)
+  n = gfc_omp_get_nm_list (c, OMP_LIST_MAP);
+  for (; n != NULL; n = n->next)
     {
       gfc_symbol *s = n->sym;
 
@@ -2423,7 +2518,7 @@  gfc_match_oacc_update (void)
       != MATCH_YES)
     return MATCH_ERROR;
 
-  if (!c->lists[OMP_LIST_MAP])
+  if (!gfc_omp_get_nm_list (c, OMP_LIST_MAP))
     {
       gfc_error ("%<acc update%> must contain at least one "
 		 "%<device%> or %<host%> or %<self%> clause at %L", &here);
@@ -2501,9 +2596,9 @@  gfc_match_oacc_cache (void)
      subarrays", which we're currently not checking here.  Either check this
      after the call of gfc_match_omp_variable_list, or add something like a
      only_sections variant next to its allow_sections parameter.  */
-  match m = gfc_match_omp_variable_list (" (",
-					 &c->lists[OMP_LIST_CACHE], true,
-					 NULL, NULL, true);
+  match m = gfc_match_omp_variable_list (
+	      " (", gfc_omp_get_nm_ref (c, OMP_LIST_CACHE),
+	      true, NULL, NULL, true);
   if (m != MATCH_YES)
     {
       gfc_free_omp_clauses(c);
@@ -2911,7 +3006,7 @@  gfc_match_omp_do_simd (void)
 match
 gfc_match_omp_flush (void)
 {
-  gfc_omp_namelist *list = NULL;
+  gfc_omp_namelist_item *list = NULL;
   gfc_omp_clauses *c = NULL;
   gfc_gobble_whitespace ();
   enum gfc_omp_memorder mo = OMP_MEMORDER_UNSET;
@@ -2936,14 +3031,14 @@  gfc_match_omp_flush (void)
     {
       gfc_error ("List specified together with memory order clause in FLUSH "
 		 "directive at %C");
-      gfc_free_omp_namelist (list);
-      gfc_free_omp_clauses (c);
+      gfc_free_omp_namelist_item (list);
       return MATCH_ERROR;
     }
   if (gfc_match_omp_eos () != MATCH_YES)
     {
       gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
-      gfc_free_omp_namelist (list);
+      gfc_free_omp_namelist_item (list);
+      free (list);
       gfc_free_omp_clauses (c);
       return MATCH_ERROR;
     }
@@ -3387,8 +3482,7 @@  gfc_match_omp_declare_target (void)
   locus old_loc;
   match m;
   gfc_omp_clauses *c = NULL;
-  int list;
-  gfc_omp_namelist *n;
+  gfc_omp_namelist_item *n;
   gfc_symbol *s;
 
   old_loc = gfc_current_locus;
@@ -3416,7 +3510,7 @@  gfc_match_omp_declare_target (void)
     {
       c = gfc_get_omp_clauses ();
       gfc_current_locus = old_loc;
-      m = gfc_match_omp_to_link (" (", &c->lists[OMP_LIST_TO]);
+      m = gfc_match_omp_to_link (" (", gfc_omp_get_nm_ref (c, OMP_LIST_TO));
       if (m != MATCH_YES)
 	goto syntax;
       if (gfc_match_omp_eos () != MATCH_YES)
@@ -3430,17 +3524,19 @@  gfc_match_omp_declare_target (void)
 
   gfc_buffer_error (false);
 
-  for (list = OMP_LIST_TO; list != OMP_LIST_NUM;
-       list = (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM))
-    for (n = c->lists[list]; n; n = n->next)
+  for (gfc_omp_namelist *list = c->lists; list; list = list->next)
+    for (n = (list->clause == OMP_LIST_TO || list->clause == OMP_LIST_LINK)
+	     ? list->item : NULL;
+	 n; n = n->next)
       if (n->sym)
 	n->sym->mark = 0;
       else if (n->u.common->head)
 	n->u.common->head->mark = 0;
 
-  for (list = OMP_LIST_TO; list != OMP_LIST_NUM;
-       list = (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM))
-    for (n = c->lists[list]; n; n = n->next)
+  for (gfc_omp_namelist *list = c->lists; list; list = list->next)
+    for (n = (list->clause == OMP_LIST_TO || list->clause == OMP_LIST_LINK)
+	     ? list->item : NULL;
+	 n; n = n->next)
       if (n->sym)
 	{
 	  if (n->sym->attr.in_common)
@@ -3448,13 +3544,13 @@  gfc_match_omp_declare_target (void)
 			   "element of a COMMON block", &n->where);
 	  else if (n->sym->attr.omp_declare_target
 		   && n->sym->attr.omp_declare_target_link
-		   && list != OMP_LIST_LINK)
+		   && list->clause != OMP_LIST_LINK)
 	    gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
 			   "mentioned in LINK clause and later in TO clause",
 			   &n->where);
 	  else if (n->sym->attr.omp_declare_target
 		   && !n->sym->attr.omp_declare_target_link
-		   && list == OMP_LIST_LINK)
+		   && list->clause == OMP_LIST_LINK)
 	    gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
 			   "mentioned in TO clause and later in LINK clause",
 			   &n->where);
@@ -3465,7 +3561,7 @@  gfc_match_omp_declare_target (void)
 	  else if (gfc_add_omp_declare_target (&n->sym->attr, n->sym->name,
 					       &n->sym->declared_at))
 	    {
-	      if (list == OMP_LIST_LINK)
+	      if (list->clause == OMP_LIST_LINK)
 		gfc_add_omp_declare_target_link (&n->sym->attr, n->sym->name,
 						 &n->sym->declared_at);
 	    }
@@ -3482,13 +3578,13 @@  gfc_match_omp_declare_target (void)
 	}
       else if (n->u.common->omp_declare_target
 	       && n->u.common->omp_declare_target_link
-	       && list != OMP_LIST_LINK)
+	       && list->clause != OMP_LIST_LINK)
 	gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
 		       "mentioned in LINK clause and later in TO clause",
 		       &n->where);
       else if (n->u.common->omp_declare_target
 	       && !n->u.common->omp_declare_target_link
-	       && list == OMP_LIST_LINK)
+	       && list->clause == OMP_LIST_LINK)
 	gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
 		       "mentioned in TO clause and later in LINK clause",
 		       &n->where);
@@ -3499,7 +3595,8 @@  gfc_match_omp_declare_target (void)
       else
 	{
 	  n->u.common->omp_declare_target = 1;
-	  n->u.common->omp_declare_target_link = (list == OMP_LIST_LINK);
+	  n->u.common->omp_declare_target_link
+	    = (list->clause == OMP_LIST_LINK);
 	  if (n->u.common->omp_device_type != OMP_DEVICE_TYPE_UNSET
 	      && n->u.common->omp_device_type != c->device_type)
 	    gfc_error_now ("COMMON at %L set in previous OMP DECLARE "
@@ -3513,7 +3610,7 @@  gfc_match_omp_declare_target (void)
 	      if (gfc_add_omp_declare_target (&s->attr, s->name,
 					      &s->declared_at))
 		{
-		  if (list == OMP_LIST_LINK)
+		  if (list->clause == OMP_LIST_LINK)
 		    gfc_add_omp_declare_target_link (&s->attr, s->name,
 						     &s->declared_at);
 		}
@@ -3525,7 +3622,9 @@  gfc_match_omp_declare_target (void)
 	      s->attr.omp_device_type = c->device_type;
 	    }
 	}
-  if (c->device_type && !c->lists[OMP_LIST_TO] && !c->lists[OMP_LIST_LINK])
+  if (c->device_type
+      && !gfc_omp_get_nm_list (c, OMP_LIST_TO)
+      && !gfc_omp_get_nm_list (c, OMP_LIST_LINK))
     gfc_warning_now (0, "OMP DECLARE TARGET directive at %L with only "
 			"DEVICE_TYPE clause is ignored", &old_loc);
 
@@ -4561,7 +4660,7 @@  resolve_omp_udr_callback2 (gfc_expr **e, int *, void *)
 
 
 static gfc_code *
-resolve_omp_udr_clause (gfc_omp_namelist *n, gfc_namespace *ns,
+resolve_omp_udr_clause (gfc_omp_namelist_item *n, gfc_namespace *ns,
 			gfc_symbol *sym1, gfc_symbol *sym2)
 {
   gfc_code *copy;
@@ -4619,21 +4718,11 @@  static void
 resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		     gfc_namespace *ns, bool openacc = false)
 {
-  gfc_omp_namelist *n;
+  gfc_omp_namelist_item *n;
   gfc_expr_list *el;
-  int list;
   int ifc;
   bool if_without_mod = false;
   gfc_omp_linear_op linear_op = OMP_LINEAR_DEFAULT;
-  static const char *clause_names[]
-    = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
-	"COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
-	"TO", "FROM", "REDUCTION", "REDUCTION" /*inscan*/, "REDUCTION" /*task*/,
-	"IN_REDUCTION", "TASK_REDUCTION",
-	"DEVICE_RESIDENT", "LINK", "USE_DEVICE",
-	"CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR",
-	"NONTEMPORAL" };
-  STATIC_ASSERT (ARRAY_SIZE (clause_names) == OMP_LIST_NUM);
 
   if (omp_clauses == NULL)
     return;
@@ -4807,8 +4896,8 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 
   /* Check that no symbol appears on multiple clauses, except that
      a symbol can appear on both firstprivate and lastprivate.  */
-  for (list = 0; list < OMP_LIST_NUM; list++)
-    for (n = omp_clauses->lists[list]; n; n = n->next)
+  for (gfc_omp_namelist *list = omp_clauses->lists; list; list = list->next)
+    for (n = list->item; n; n = n->next)
       {
 	n->sym->mark = 0;
 	n->sym->comp_mark = 0;
@@ -4849,7 +4938,7 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		  continue;
 	      }
 	  }
-	if (list == OMP_LIST_MAP
+	if (list->clause == OMP_LIST_MAP
 	    && n->sym->attr.flavor == FL_PARAMETER)
 	  {
 	    if (openacc)
@@ -4866,20 +4955,20 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		     &n->where);
       }
 
-  for (list = 0; list < OMP_LIST_NUM; list++)
-    if (list != OMP_LIST_FIRSTPRIVATE
-	&& list != OMP_LIST_LASTPRIVATE
-	&& list != OMP_LIST_ALIGNED
-	&& list != OMP_LIST_DEPEND
-	&& (list != OMP_LIST_MAP || openacc)
-	&& list != OMP_LIST_FROM
-	&& list != OMP_LIST_TO
-	&& (list != OMP_LIST_REDUCTION || !openacc)
-	&& list != OMP_LIST_REDUCTION_INSCAN
-	&& list != OMP_LIST_REDUCTION_TASK
-	&& list != OMP_LIST_IN_REDUCTION
-	&& list != OMP_LIST_TASK_REDUCTION)
-      for (n = omp_clauses->lists[list]; n; n = n->next)
+  for (gfc_omp_namelist *list = omp_clauses->lists; list; list = list->next)
+    if (list->clause != OMP_LIST_FIRSTPRIVATE
+	&& list->clause != OMP_LIST_LASTPRIVATE
+	&& list->clause != OMP_LIST_ALIGNED
+	&& list->clause != OMP_LIST_DEPEND
+	&& (list->clause != OMP_LIST_MAP || openacc)
+	&& list->clause != OMP_LIST_FROM
+	&& list->clause != OMP_LIST_TO
+	&& (list->clause != OMP_LIST_REDUCTION || !openacc)
+	&& list->clause != OMP_LIST_REDUCTION_INSCAN
+	&& list->clause != OMP_LIST_REDUCTION_TASK
+	&& list->clause != OMP_LIST_IN_REDUCTION
+	&& list->clause != OMP_LIST_TASK_REDUCTION)
+      for (n = list->item; n; n = n->next)
 	{
 	  bool component_ref_p = false;
 
@@ -4904,18 +4993,19 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		n->sym->mark = 1;
 	    }
 	}
+  for (gfc_omp_namelist *list = omp_clauses->lists; list; list = list->next)
+    if (list->clause == OMP_LIST_FIRSTPRIVATE
+	|| list->clause == OMP_LIST_LASTPRIVATE)
+      for (n = list->item; n; n = n->next)
+	if (n->sym->mark)
+	  {
+	    gfc_error ("Symbol %qs present on multiple clauses at %L",
+		       n->sym->name, &n->where);
+	    n->sym->mark = 0;
+	  }
 
-  gcc_assert (OMP_LIST_LASTPRIVATE == OMP_LIST_FIRSTPRIVATE + 1);
-  for (list = OMP_LIST_FIRSTPRIVATE; list <= OMP_LIST_LASTPRIVATE; list++)
-    for (n = omp_clauses->lists[list]; n; n = n->next)
-      if (n->sym->mark)
-	{
-	  gfc_error ("Symbol %qs present on multiple clauses at %L",
-		     n->sym->name, &n->where);
-	  n->sym->mark = 0;
-	}
-
-  for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_FIRSTPRIVATE);
+       n; n = n->next)
     {
       if (n->sym->mark)
 	gfc_error ("Symbol %qs present on multiple clauses at %L",
@@ -4923,10 +5013,12 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
       else
 	n->sym->mark = 1;
     }
-  for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_LASTPRIVATE);
+       n; n = n->next)
     n->sym->mark = 0;
 
-  for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_LASTPRIVATE);
+       n; n = n->next)
     {
       if (n->sym->mark)
 	gfc_error ("Symbol %qs present on multiple clauses at %L",
@@ -4935,10 +5027,10 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	n->sym->mark = 1;
     }
 
-  for (n = omp_clauses->lists[OMP_LIST_ALIGNED]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_ALIGNED); n; n = n->next)
     n->sym->mark = 0;
 
-  for (n = omp_clauses->lists[OMP_LIST_ALIGNED]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_ALIGNED); n; n = n->next)
     {
       if (n->sym->mark)
 	gfc_error ("Symbol %qs present on multiple clauses at %L",
@@ -4950,10 +5042,12 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
   /* OpenACC reductions.  */
   if (openacc)
     {
-      for (n = omp_clauses->lists[OMP_LIST_REDUCTION]; n; n = n->next)
+      for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_REDUCTION);
+	   n; n = n->next)
 	n->sym->mark = 0;
 
-      for (n = omp_clauses->lists[OMP_LIST_REDUCTION]; n; n = n->next)
+      for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_REDUCTION);
+	   n; n = n->next)
 	{
 	  if (n->sym->mark)
 	    gfc_error ("Symbol %qs present on multiple clauses at %L",
@@ -4968,12 +5062,12 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	}
     }
   
-  for (n = omp_clauses->lists[OMP_LIST_TO]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_TO); n; n = n->next)
     n->sym->mark = 0;
-  for (n = omp_clauses->lists[OMP_LIST_FROM]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_FROM); n; n = n->next)
     if (n->expr == NULL)
       n->sym->mark = 1;
-  for (n = omp_clauses->lists[OMP_LIST_TO]; n; n = n->next)
+  for (n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_TO); n; n = n->next)
     {
       if (n->expr == NULL && n->sym->mark)
 	gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
@@ -4982,12 +5076,12 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	n->sym->mark = 1;
     }
 
-  for (list = 0; list < OMP_LIST_NUM; list++)
-    if ((n = omp_clauses->lists[list]) != NULL)
+  for (gfc_omp_namelist *list = omp_clauses->lists; list; list = list->next)
       {
-	const char *name = clause_names[list];
+	const char *name = gfc_omp_get_clause_name (list->clause);
+	n = list->item;
 
-	switch (list)
+	switch (list->clause)
 	  {
 	  case OMP_LIST_COPYIN:
 	    for (; n != NULL; n = n->next)
@@ -5058,7 +5152,7 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	  case OMP_LIST_CACHE:
 	    for (; n != NULL; n = n->next)
 	      {
-		if (list == OMP_LIST_DEPEND)
+		if (list->clause == OMP_LIST_DEPEND)
 		  {
 		    if (n->u.depend_op == OMP_DEPEND_SINK_FIRST
 			|| n->u.depend_op == OMP_DEPEND_SINK)
@@ -5106,8 +5200,8 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 			   array isn't contiguous.  An expression such as
 			   arr(-n:n,-n:n) could be contiguous even if it looks
 			   like it may not be.  */
-			if (list != OMP_LIST_CACHE
-			    && list != OMP_LIST_DEPEND
+			if (list->clause != OMP_LIST_CACHE
+			    && list->clause != OMP_LIST_DEPEND
 			    && !gfc_is_simply_contiguous (n->expr, false, true)
 			    && gfc_is_not_contiguous (n->expr))
 			  gfc_error ("Array is not contiguous at %L",
@@ -5153,7 +5247,7 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 					 n->sym->name, name, &n->where);
 			      break;
 			    }
-			  else if (list == OMP_LIST_DEPEND
+			  else if (list->clause == OMP_LIST_DEPEND
 				   && ar->start[i]
 				   && ar->start[i]->expr_type == EXPR_CONSTANT
 				   && ar->end[i]
@@ -5170,25 +5264,25 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		  }
 		else if (openacc)
 		  {
-		    if (list == OMP_LIST_MAP
+		    if (list->clause == OMP_LIST_MAP
 			&& n->u.map_op == OMP_MAP_FORCE_DEVICEPTR)
 		      resolve_oacc_deviceptr_clause (n->sym, n->where, name);
 		    else
 		      resolve_oacc_data_clauses (n->sym, n->where, name);
 		  }
-		else if (list != OMP_LIST_DEPEND
+		else if (list->clause != OMP_LIST_DEPEND
 			 && n->sym->as
 			 && n->sym->as->type == AS_ASSUMED_SIZE)
 		  gfc_error ("Assumed size array %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
 		if (!openacc
-		    && list == OMP_LIST_MAP
+		    && list->clause == OMP_LIST_MAP
 		    && n->sym->ts.type == BT_DERIVED
 		    && n->sym->ts.u.derived->attr.alloc_comp)
 		  gfc_error ("List item %qs with allocatable components is not "
 			     "permitted in map clause at %L", n->sym->name,
 			     &n->where);
-		if (list == OMP_LIST_MAP && !openacc)
+		if (list->clause == OMP_LIST_MAP && !openacc)
 		  switch (code->op)
 		    {
 		    case EXEC_OMP_TARGET:
@@ -5246,8 +5340,8 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		    }
 	      }
 
-	    if (list != OMP_LIST_DEPEND)
-	      for (n = omp_clauses->lists[list]; n != NULL; n = n->next)
+	    if (list->clause != OMP_LIST_DEPEND)
+	      for (n = list->item; n != NULL; n = n->next)
 		{
 		  n->sym->attr.referenced = 1;
 		  if (n->sym->attr.threadprivate)
@@ -5284,11 +5378,12 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	    for (; n != NULL; n = n->next)
 	      {
 		bool bad = false;
-		bool is_reduction = (list == OMP_LIST_REDUCTION
-				     || list == OMP_LIST_REDUCTION_INSCAN
-				     || list == OMP_LIST_REDUCTION_TASK
-				     || list == OMP_LIST_IN_REDUCTION
-				     || list == OMP_LIST_TASK_REDUCTION);
+		bool is_reduction
+		  = (list->clause == OMP_LIST_REDUCTION
+		     || list->clause == OMP_LIST_REDUCTION_INSCAN
+		     || list->clause == OMP_LIST_REDUCTION_TASK
+		     || list->clause == OMP_LIST_IN_REDUCTION
+		     || list->clause == OMP_LIST_TASK_REDUCTION);
 		if (n->sym->attr.threadprivate)
 		  gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
@@ -5298,7 +5393,7 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		if (n->sym->attr.associate_var)
 		  gfc_error ("ASSOCIATE name %qs in %s clause at %L",
 			     n->sym->name, name, &n->where);
-		if (list != OMP_LIST_PRIVATE && is_reduction)
+		if (list->clause != OMP_LIST_PRIVATE && is_reduction)
 		  {
 		    if (n->sym->attr.proc_pointer)
 		      gfc_error ("Procedure pointer %qs in %s clause at %L",
@@ -5323,7 +5418,7 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 			     "NAMELIST statement at %L",
 			     n->sym->name, name, &n->where);
 		if (n->sym->attr.pointer && n->sym->attr.intent == INTENT_IN)
-		  switch (list)
+		  switch (list->clause)
 		    {
 		    case OMP_LIST_PRIVATE:
 		    case OMP_LIST_LASTPRIVATE:
@@ -5336,7 +5431,7 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		      break;
 		    }
 
-		switch (list)
+		switch (list->clause)
 		  {
 		  case OMP_LIST_REDUCTION_INSCAN:
 		  case OMP_LIST_REDUCTION_TASK:
@@ -5497,9 +5592,10 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 				&& expr->symtree->n.sym->attr.dummy
 				&& expr->symtree->n.sym->ns == ns)
 			      {
-				gfc_omp_namelist *n2;
-				for (n2 = omp_clauses->lists[OMP_LIST_UNIFORM];
-				     n2; n2 = n2->next)
+				gfc_omp_namelist_item *n2;
+				n2 = gfc_omp_get_nm_list (omp_clauses,
+							  OMP_LIST_UNIFORM);
+				for (; n2; n2 = n2->next)
 				  if (n2->sym == expr->symtree->n.sym)
 				    break;
 				if (n2)
@@ -5614,9 +5710,9 @@  resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 	       "on ORDERED directive at %L", &code->loc);
   if (!openacc
       && code
-      && omp_clauses->lists[OMP_LIST_MAP] == NULL
-      && omp_clauses->lists[OMP_LIST_USE_DEVICE_PTR] == NULL
-      && omp_clauses->lists[OMP_LIST_USE_DEVICE_ADDR] == NULL)
+      && !gfc_omp_get_nm_list (omp_clauses, OMP_LIST_MAP)
+      && !gfc_omp_get_nm_list (omp_clauses, OMP_LIST_USE_DEVICE_PTR)
+      && !gfc_omp_get_nm_list (omp_clauses, OMP_LIST_USE_DEVICE_ADDR))
     {
       const char *p = NULL;
       switch (code->op)
@@ -6163,8 +6259,7 @@  gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
 {
   struct fortran_omp_context ctx;
   gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
-  gfc_omp_namelist *n;
-  int list;
+  gfc_omp_namelist_item *n;
 
   ctx.code = code;
   ctx.sharing_clauses = new hash_set<gfc_symbol *>;
@@ -6173,8 +6268,8 @@  gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
   ctx.is_openmp = true;
   omp_current_ctx = &ctx;
 
-  for (list = 0; list < OMP_LIST_NUM; list++)
-    switch (list)
+  for (gfc_omp_namelist *list = omp_clauses->lists; list; list = list->next)
+    switch (list->clause)
       {
       case OMP_LIST_SHARED:
       case OMP_LIST_PRIVATE:
@@ -6186,7 +6281,7 @@  gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
       case OMP_LIST_IN_REDUCTION:
       case OMP_LIST_TASK_REDUCTION:
       case OMP_LIST_LINEAR:
-	for (n = omp_clauses->lists[list]; n; n = n->next)
+	for (n = list->item; n; n = n->next)
 	  ctx.sharing_clauses->add (n->sym);
 	break;
       default:
@@ -6284,13 +6379,13 @@  gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym, bool add_clause)
 
   if (! omp_current_ctx->private_iterators->add (sym) && add_clause)
     {
+      gfc_omp_namelist_item **list;
       gfc_omp_clauses *omp_clauses = omp_current_ctx->code->ext.omp_clauses;
-      gfc_omp_namelist *p;
-
-      p = gfc_get_omp_namelist ();
+      list = gfc_omp_get_nm_ref (omp_clauses, OMP_LIST_PRIVATE);
+      gfc_omp_namelist_item *p = gfc_get_omp_namelist_item ();
       p->sym = sym;
-      p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
-      omp_clauses->lists[OMP_LIST_PRIVATE] = p;
+      p->next = *list;
+      *list = p;
     }
 }
 
@@ -6315,8 +6410,8 @@  static void
 resolve_omp_do (gfc_code *code)
 {
   gfc_code *do_code, *c;
-  int list, i, collapse;
-  gfc_omp_namelist *n;
+  int i, collapse;
+  gfc_omp_namelist_item *n;
   gfc_symbol *dovar;
   const char *name;
   bool is_simd = false;
@@ -6421,12 +6516,15 @@  resolve_omp_do (gfc_code *code)
 	gfc_error ("%s iteration variable must not be THREADPRIVATE "
 		   "at %L", name, &do_code->loc);
       if (code->ext.omp_clauses)
-	for (list = 0; list < OMP_LIST_NUM; list++)
+	for (gfc_omp_namelist *list = code->ext.omp_clauses->lists;
+	     list; list = list->next)
 	  if (!is_simd || code->ext.omp_clauses->collapse > 1
-	      ? (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
-	      : (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE
-		 && list != OMP_LIST_LINEAR))
-	    for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
+	      ? (list->clause != OMP_LIST_PRIVATE
+		 && list->clause != OMP_LIST_LASTPRIVATE)
+	      : (list->clause != OMP_LIST_PRIVATE
+		 && list->clause != OMP_LIST_LASTPRIVATE
+		 && list->clause != OMP_LIST_LINEAR))
+	    for (n = list->item; n; n = n->next)
 	      if (dovar == n->sym)
 		{
 		  if (!is_simd || code->ext.omp_clauses->collapse > 1)
@@ -6786,8 +6884,7 @@  gfc_resolve_oacc_blocks (gfc_code *code, gfc_namespace *ns)
 {
   fortran_omp_context ctx;
   gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
-  gfc_omp_namelist *n;
-  int list;
+  gfc_omp_namelist_item *n;
 
   resolve_oacc_loop_blocks (code);
 
@@ -6798,11 +6895,11 @@  gfc_resolve_oacc_blocks (gfc_code *code, gfc_namespace *ns)
   ctx.is_openmp = false;
   omp_current_ctx = &ctx;
 
-  for (list = 0; list < OMP_LIST_NUM; list++)
-    switch (list)
+  for (gfc_omp_namelist *list = omp_clauses->lists; list; list = list->next)
+    switch (list->clause)
       {
       case OMP_LIST_PRIVATE:
-	for (n = omp_clauses->lists[list]; n; n = n->next)
+	for (n = list->item; n; n = n->next)
 	  ctx.sharing_clauses->add (n->sym);
 	break;
       default:
@@ -6849,8 +6946,7 @@  resolve_oacc_loop (gfc_code *code)
 void
 gfc_resolve_oacc_declare (gfc_namespace *ns)
 {
-  int list;
-  gfc_omp_namelist *n;
+  gfc_omp_namelist_item *n;
   gfc_oacc_declare *oc;
 
   if (ns->oacc_declare == NULL)
@@ -6858,8 +6954,8 @@  gfc_resolve_oacc_declare (gfc_namespace *ns)
 
   for (oc = ns->oacc_declare; oc; oc = oc->next)
     {
-      for (list = 0; list < OMP_LIST_NUM; list++)
-	for (n = oc->clauses->lists[list]; n; n = n->next)
+      for (gfc_omp_namelist *list = oc->clauses->lists; list; list = list->next)
+	for (n = list->item; n; n = n->next)
 	  {
 	    n->sym->mark = 0;
 	    if (n->sym->attr.flavor != FL_VARIABLE
@@ -6879,14 +6975,15 @@  gfc_resolve_oacc_declare (gfc_namespace *ns)
 	      }
 	  }
 
-      for (n = oc->clauses->lists[OMP_LIST_DEVICE_RESIDENT]; n; n = n->next)
+      n = gfc_omp_get_nm_list (oc->clauses, OMP_LIST_DEVICE_RESIDENT);
+      for (; n; n = n->next)
 	check_array_not_assumed (n->sym, oc->loc, "DEVICE_RESIDENT");
     }
 
   for (oc = ns->oacc_declare; oc; oc = oc->next)
     {
-      for (list = 0; list < OMP_LIST_NUM; list++)
-	for (n = oc->clauses->lists[list]; n; n = n->next)
+      for (gfc_omp_namelist *list = oc->clauses->lists; list; list = list->next)
+	for (n = list->item; n; n = n->next)
 	  {
 	    if (n->sym->mark)
 	      {
@@ -6901,8 +6998,8 @@  gfc_resolve_oacc_declare (gfc_namespace *ns)
 
   for (oc = ns->oacc_declare; oc; oc = oc->next)
     {
-      for (list = 0; list < OMP_LIST_NUM; list++)
-	for (n = oc->clauses->lists[list]; n; n = n->next)
+      for (gfc_omp_namelist *list = oc->clauses->lists; list; list = list->next)
+	for (n = list->item; n; n = n->next)
 	  n->sym->mark = 0;
     }
 }
@@ -7027,8 +7124,8 @@  gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
       if (code->ext.omp_clauses)
 	resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
       if (code->ext.omp_clauses == NULL
-	  || (code->ext.omp_clauses->lists[OMP_LIST_TO] == NULL
-	      && code->ext.omp_clauses->lists[OMP_LIST_FROM] == NULL))
+	  || (!gfc_omp_get_nm_list (code->ext.omp_clauses, OMP_LIST_TO)
+	      && !gfc_omp_get_nm_list (code->ext.omp_clauses, OMP_LIST_FROM)))
 	gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
 		   "FROM clause", &code->loc);
       break;
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index ec7abc240d6..3f4358ca348 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -5434,9 +5434,13 @@  parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only)
       new_st.ext.omp_name = NULL;
       break;
     case EXEC_OMP_END_SINGLE:
-      cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]
-	= new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE];
-      new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] = NULL;
+      if (cp->ext.omp_clauses->lists && new_st.ext.omp_clauses->lists)
+	{
+	  gcc_assert (!new_st.ext.omp_clauses->lists->next);
+	  new_st.ext.omp_clauses->lists->next = cp->ext.omp_clauses->lists;
+	}
+      cp->ext.omp_clauses->lists = new_st.ext.omp_clauses->lists;
+      new_st.ext.omp_clauses->lists = NULL;
       gfc_free_omp_clauses (new_st.ext.omp_clauses);
       break;
     case EXEC_NOP:
diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c
index a3b0f12b171..6e4b0ada171 100644
--- a/gcc/fortran/st.c
+++ b/gcc/fortran/st.c
@@ -265,7 +265,7 @@  gfc_free_statement (gfc_code *p)
       break;
 
     case EXEC_OMP_FLUSH:
-      gfc_free_omp_namelist (p->ext.omp_namelist);
+      gfc_free_omp_namelist_item (p->ext.omp_namelist);
       break;
 
     case EXEC_OMP_BARRIER:
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 71d5c670e55..e0bdbc0e5b4 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -6603,19 +6603,27 @@  static gfc_omp_clauses *module_oacc_clauses;
 static void
 add_clause (gfc_symbol *sym, gfc_omp_map_op map_op)
 {
-  gfc_omp_namelist *n;
+  gfc_omp_namelist *list;
+  gfc_omp_namelist_item *n;
 
-  n = gfc_get_omp_namelist ();
+  n = gfc_get_omp_namelist_item ();
   n->sym = sym;
   n->u.map_op = map_op;
 
   if (!module_oacc_clauses)
     module_oacc_clauses = gfc_get_omp_clauses ();
 
-  if (module_oacc_clauses->lists[OMP_LIST_MAP])
-    n->next = module_oacc_clauses->lists[OMP_LIST_MAP];
-
-  module_oacc_clauses->lists[OMP_LIST_MAP] = n;
+  for (list = module_oacc_clauses->lists; list; list = list->next)
+    if (list->clause == OMP_LIST_MAP)
+      break;
+  if (list)
+    n->next = list->item;
+  else
+    {
+      module_oacc_clauses->lists = list = gfc_get_omp_namelist ();
+      list->clause = OMP_LIST_MAP;
+    }
+  list->item = n;
 }
 
 
@@ -6657,7 +6665,7 @@  finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
   gfc_oacc_declare *oc;
   locus where = gfc_current_locus;
   gfc_omp_clauses *omp_clauses = NULL;
-  gfc_omp_namelist *n, *p;
+  gfc_omp_namelist_item *n, *p;
 
   module_oacc_clauses = NULL;
   gfc_traverse_ns (ns, find_module_oacc_declare_clauses);
@@ -6685,8 +6693,10 @@  finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
 	gfc_error ("Sorry, !$ACC DECLARE at %L is not allowed "
 		   "in BLOCK construct", &oc->loc);
 
-
-      if (oc->clauses && oc->clauses->lists[OMP_LIST_MAP])
+      gfc_omp_namelist_item *oc_list;
+      oc_list = (oc->clauses ? gfc_omp_get_nm_list (oc->clauses, OMP_LIST_MAP)
+			     : NULL);
+      if (oc_list)
 	{
 	  if (omp_clauses == NULL)
 	    {
@@ -6694,12 +6704,12 @@  finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
 	      continue;
 	    }
 
-	  for (n = oc->clauses->lists[OMP_LIST_MAP]; n; p = n, n = n->next)
+	  for (n = oc_list; n; p = n, n = n->next)
 	    ;
 
 	  gcc_assert (p->next == NULL);
 
-	  p->next = omp_clauses->lists[OMP_LIST_MAP];
+	  p->next = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_MAP);
 	  omp_clauses = oc->clauses;
 	}
     }
@@ -6707,7 +6717,8 @@  finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
   if (!omp_clauses)
     return;
 
-  for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
+  n = gfc_omp_get_nm_list (omp_clauses, OMP_LIST_MAP);
+  for (; n; n = n->next)
     {
       switch (n->u.map_op)
 	{
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 6b4ad6a7050..c067d808f8d 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -1694,7 +1694,7 @@  gfc_trans_omp_variable (gfc_symbol *sym, bool declare_simd)
 
 static tree
 gfc_trans_omp_variable_list (enum omp_clause_code code,
-			     gfc_omp_namelist *namelist, tree list,
+			     gfc_omp_namelist_item *namelist, tree list,
 			     bool declare_simd)
 {
   for (; namelist != NULL; namelist = namelist->next)
@@ -1734,7 +1734,7 @@  omp_udr_find_orig (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
 }
 
 static void
-gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
+gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist_item *n, locus where)
 {
   gfc_symbol *sym = n->sym;
   gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
@@ -2033,7 +2033,8 @@  gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
 }
 
 static tree
-gfc_trans_omp_reduction_list (int kind, gfc_omp_namelist *namelist, tree list,
+gfc_trans_omp_reduction_list (enum omp_list_clauses kind,
+			      gfc_omp_namelist_item *namelist, tree list,
 			      locus where, bool mark_addressable)
 {
   omp_clause_code clause = OMP_CLAUSE_REDUCTION;
@@ -2142,7 +2143,7 @@  static vec<tree, va_heap, vl_embed> *doacross_steps;
 /* Translate an array section or array element.  */
 
 static void
-gfc_trans_omp_array_section (stmtblock_t *block, gfc_omp_namelist *n,
+gfc_trans_omp_array_section (stmtblock_t *block, gfc_omp_namelist_item *n,
 			     tree decl, bool element, gomp_map_kind ptr_kind,
 			     tree &node, tree &node2, tree &node3, tree &node4)
 {
@@ -2275,20 +2276,20 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		       bool openacc = false)
 {
   tree omp_clauses = NULL_TREE, chunk_size, c;
-  int list, ifc;
+  int ifc;
   enum omp_clause_code clause_code;
   gfc_se se;
 
   if (clauses == NULL)
     return NULL_TREE;
 
-  for (list = 0; list < OMP_LIST_NUM; list++)
+  for (gfc_omp_namelist *list = clauses->lists; list; list = list->next)
     {
-      gfc_omp_namelist *n = clauses->lists[list];
+      gfc_omp_namelist_item *n = list->item;
 
       if (n == NULL)
 	continue;
-      switch (list)
+      switch (list->clause)
 	{
 	case OMP_LIST_REDUCTION:
 	case OMP_LIST_REDUCTION_INSCAN:
@@ -2297,8 +2298,9 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 	case OMP_LIST_TASK_REDUCTION:
 	  /* An OpenACC async clause indicates the need to set reduction
 	     arguments addressable, to allow asynchronous copy-out.  */
-	  omp_clauses = gfc_trans_omp_reduction_list (list, n, omp_clauses,
-						      where, clauses->async);
+	  omp_clauses = gfc_trans_omp_reduction_list (list->clause, n,
+						      omp_clauses, where,
+						      clauses->async);
 	  break;
 	case OMP_LIST_PRIVATE:
 	  clause_code = OMP_CLAUSE_PRIVATE;
@@ -3162,7 +3164,7 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 	      if (!n->sym->attr.referenced)
 		continue;
 
-	      switch (list)
+	      switch (list->clause)
 		{
 		case OMP_LIST_TO:
 		  clause_code = OMP_CLAUSE_TO;
@@ -4445,9 +4447,9 @@  gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
 
       if (clauses)
 	{
-	  gfc_omp_namelist *n = NULL;
+	  gfc_omp_namelist_item *n = NULL;
 	  if (op == EXEC_OMP_SIMD && collapse == 1)
-	    for (n = clauses->lists[OMP_LIST_LINEAR];
+	    for (n = gfc_omp_get_nm_list (clauses, OMP_LIST_LINEAR);
 		 n != NULL; n = n->next)
 	      if (code->ext.iterator->var->symtree->n.sym == n->sym)
 		{
@@ -4455,7 +4457,7 @@  gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
 		  break;
 		}
 	  if (n == NULL && op != EXEC_OMP_DISTRIBUTE)
-	    for (n = clauses->lists[OMP_LIST_LASTPRIVATE];
+	    for (n = gfc_omp_get_nm_list (clauses, OMP_LIST_LASTPRIVATE);
 		 n != NULL; n = n->next)
 	      if (code->ext.iterator->var->symtree->n.sym == n->sym)
 		{
@@ -4463,7 +4465,8 @@  gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
 		  break;
 		}
 	  if (n == NULL)
-	    for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
+	    for (n = gfc_omp_get_nm_list (clauses, OMP_LIST_PRIVATE);
+		 n != NULL; n = n->next)
 	      if (code->ext.iterator->var->symtree->n.sym == n->sym)
 		{
 		  dovar_found = 1;
@@ -4791,10 +4794,22 @@  gfc_trans_oacc_combined_directive (gfc_code *code)
       loop_clauses.par_auto = construct_clauses.par_auto;
       loop_clauses.independent = construct_clauses.independent;
       loop_clauses.tile_list = construct_clauses.tile_list;
-      loop_clauses.lists[OMP_LIST_PRIVATE]
-	= construct_clauses.lists[OMP_LIST_PRIVATE];
-      loop_clauses.lists[OMP_LIST_REDUCTION]
-	= construct_clauses.lists[OMP_LIST_REDUCTION];
+      for (gfc_omp_namelist *list = construct_clauses.lists;
+	   list; list = list->next)
+	{
+	  if (list->clause == OMP_LIST_PRIVATE)
+	    {
+	      *gfc_omp_get_nm_ref (&loop_clauses, OMP_LIST_PRIVATE) = list->item;
+	      list->item = NULL;
+	    }
+	  else if (list->clause == OMP_LIST_REDUCTION)
+	    {
+	      *gfc_omp_get_nm_ref (&loop_clauses, OMP_LIST_REDUCTION)
+		= list->item;
+	      if (construct_code == OACC_KERNELS)
+		list->item = NULL;
+	    }
+	}
       construct_clauses.gang = false;
       construct_clauses.gang_static = false;
       construct_clauses.gang_num_expr = NULL;
@@ -4808,9 +4823,6 @@  gfc_trans_oacc_combined_directive (gfc_code *code)
       construct_clauses.independent = false;
       construct_clauses.independent = false;
       construct_clauses.tile_list = NULL;
-      construct_clauses.lists[OMP_LIST_PRIVATE] = NULL;
-      if (construct_code == OACC_KERNELS)
-	construct_clauses.lists[OMP_LIST_REDUCTION] = NULL;
       oacc_clauses = gfc_trans_omp_clauses (&block, &construct_clauses,
 					    code->loc, false, true);
     }
@@ -4923,6 +4935,17 @@  enum
 };
 
 static void
+gfc_copy_list_clauses (gfc_omp_clauses *to, gfc_omp_clauses *from,
+		       enum omp_list_clauses clause)
+{
+  gfc_omp_namelist_item *list = gfc_omp_get_nm_list (from, clause);
+  if (list)
+    *gfc_omp_get_nm_ref (to, clause) = list;
+}
+
+/* Return true if actual splitting was done.  */
+
+bool
 gfc_split_omp_clauses (gfc_code *code,
 		       gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM])
 {
@@ -5045,17 +5068,17 @@  gfc_split_omp_clauses (gfc_code *code,
   if (mask == 0)
     {
       clausesa[innermost] = *code->ext.omp_clauses;
-      return;
+      return false;
     }
   if (code->ext.omp_clauses != NULL)
     {
       if (mask & GFC_OMP_MASK_TARGET)
 	{
 	  /* First the clauses that are unique to some constructs.  */
-	  clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_MAP]
-	    = code->ext.omp_clauses->lists[OMP_LIST_MAP];
-	  clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IS_DEVICE_PTR]
-	    = code->ext.omp_clauses->lists[OMP_LIST_IS_DEVICE_PTR];
+	  gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TARGET],
+				 code->ext.omp_clauses, OMP_LIST_MAP);
+	  gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TARGET],
+				 code->ext.omp_clauses, OMP_LIST_IS_DEVICE_PTR);
 	  clausesa[GFC_OMP_SPLIT_TARGET].device
 	    = code->ext.omp_clauses->device;
 	  clausesa[GFC_OMP_SPLIT_TARGET].defaultmap
@@ -5075,8 +5098,8 @@  gfc_split_omp_clauses (gfc_code *code,
 	    = code->ext.omp_clauses->thread_limit;
 	  /* Shared and default clauses are allowed on parallel, teams
 	     and taskloop.  */
-	  clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_SHARED]
-	    = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
+	  gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TEAMS],
+				 code->ext.omp_clauses, OMP_LIST_SHARED);
 	  clausesa[GFC_OMP_SPLIT_TEAMS].default_sharing
 	    = code->ext.omp_clauses->default_sharing;
 	}
@@ -5096,16 +5119,16 @@  gfc_split_omp_clauses (gfc_code *code,
       if (mask & GFC_OMP_MASK_PARALLEL)
 	{
 	  /* First the clauses that are unique to some constructs.  */
-	  clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_COPYIN]
-	    = code->ext.omp_clauses->lists[OMP_LIST_COPYIN];
+	  gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_PARALLEL],
+				 code->ext.omp_clauses, OMP_LIST_COPYIN);
 	  clausesa[GFC_OMP_SPLIT_PARALLEL].num_threads
 	    = code->ext.omp_clauses->num_threads;
 	  clausesa[GFC_OMP_SPLIT_PARALLEL].proc_bind
 	    = code->ext.omp_clauses->proc_bind;
 	  /* Shared and default clauses are allowed on parallel, teams
 	     and taskloop.  */
-	  clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_SHARED]
-	    = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
+	  gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_PARALLEL],
+				 code->ext.omp_clauses, OMP_LIST_SHARED);
 	  clausesa[GFC_OMP_SPLIT_PARALLEL].default_sharing
 	    = code->ext.omp_clauses->default_sharing;
 	  clausesa[GFC_OMP_SPLIT_PARALLEL].if_exprs[OMP_IF_PARALLEL]
@@ -5146,8 +5169,8 @@  gfc_split_omp_clauses (gfc_code *code,
 	    = code->ext.omp_clauses->safelen_expr;
 	  clausesa[GFC_OMP_SPLIT_SIMD].simdlen_expr
 	    = code->ext.omp_clauses->simdlen_expr;
-	  clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_ALIGNED]
-	    = code->ext.omp_clauses->lists[OMP_LIST_ALIGNED];
+	  gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_SIMD],
+				 code->ext.omp_clauses, OMP_LIST_ALIGNED);
 	  /* Duplicate collapse.  */
 	  clausesa[GFC_OMP_SPLIT_SIMD].collapse
 	    = code->ext.omp_clauses->collapse;
@@ -5183,8 +5206,8 @@  gfc_split_omp_clauses (gfc_code *code,
 	    = code->ext.omp_clauses->if_expr;
 	  /* Shared and default clauses are allowed on parallel, teams
 	     and taskloop.  */
-	  clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_SHARED]
-	    = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
+	  gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TASKLOOP],
+				 code->ext.omp_clauses, OMP_LIST_SHARED);
 	  clausesa[GFC_OMP_SPLIT_TASKLOOP].default_sharing
 	    = code->ext.omp_clauses->default_sharing;
 	  /* Duplicate collapse.  */
@@ -5195,75 +5218,92 @@  gfc_split_omp_clauses (gfc_code *code,
 	 it is enough to put it on the innermost one.  For
 	 !$ omp parallel do put it on parallel though,
 	 as that's what we did for OpenMP 3.1.  */
-      clausesa[innermost == GFC_OMP_SPLIT_DO
-	       ? (int) GFC_OMP_SPLIT_PARALLEL
-	       : innermost].lists[OMP_LIST_PRIVATE]
-	= code->ext.omp_clauses->lists[OMP_LIST_PRIVATE];
+      gfc_copy_list_clauses (&clausesa[innermost == GFC_OMP_SPLIT_DO
+				       ? (int) GFC_OMP_SPLIT_PARALLEL
+				       : innermost],
+			     code->ext.omp_clauses, OMP_LIST_PRIVATE);
       /* Firstprivate clause is supported on all constructs but
 	 simd.  Put it on the outermost of those and duplicate
 	 on parallel and teams.  */
       if (mask & GFC_OMP_MASK_TARGET)
-	clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_FIRSTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TARGET],
+			       code->ext.omp_clauses, OMP_LIST_FIRSTPRIVATE);
       if (mask & GFC_OMP_MASK_TEAMS)
-	clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_FIRSTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TEAMS],
+			       code->ext.omp_clauses, OMP_LIST_FIRSTPRIVATE);
       else if (mask & GFC_OMP_MASK_DISTRIBUTE)
-	clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_FIRSTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
+			       code->ext.omp_clauses, OMP_LIST_FIRSTPRIVATE);
       if (mask & GFC_OMP_MASK_PARALLEL)
-	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_FIRSTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_PARALLEL],
+			       code->ext.omp_clauses, OMP_LIST_FIRSTPRIVATE);
       else if (mask & GFC_OMP_MASK_DO)
-	clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_FIRSTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_DO],
+			       code->ext.omp_clauses, OMP_LIST_FIRSTPRIVATE);
       /* Lastprivate is allowed on distribute, do and simd.
          In parallel do{, simd} we actually want to put it on
 	 parallel rather than do.  */
       if (mask & GFC_OMP_MASK_DISTRIBUTE)
-	clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_LASTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
+			       code->ext.omp_clauses, OMP_LIST_LASTPRIVATE);
       if (mask & GFC_OMP_MASK_PARALLEL)
-	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_LASTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_PARALLEL],
+			       code->ext.omp_clauses, OMP_LIST_LASTPRIVATE);
       else if (mask & GFC_OMP_MASK_DO)
-	clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_LASTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_DO],
+			       code->ext.omp_clauses, OMP_LIST_LASTPRIVATE);
       if (mask & GFC_OMP_MASK_SIMD)
-	clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LASTPRIVATE]
-	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_SIMD],
+			       code->ext.omp_clauses, OMP_LIST_LASTPRIVATE);
       /* Reduction is allowed on simd, do, parallel and teams.
 	 Duplicate it on all of them, but omit on do if
 	 parallel is present.  */
-      for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
-	{
-	  if (mask & GFC_OMP_MASK_TEAMS)
-	    clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
-	      = code->ext.omp_clauses->lists[i];
-	  if (mask & GFC_OMP_MASK_PARALLEL)
-	    clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
-	      = code->ext.omp_clauses->lists[i];
-	  else if (mask & GFC_OMP_MASK_DO)
-	    clausesa[GFC_OMP_SPLIT_DO].lists[i]
-	      = code->ext.omp_clauses->lists[i];
-	  if (mask & GFC_OMP_MASK_SIMD)
-	    clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
-	      = code->ext.omp_clauses->lists[i];
-	}
+      for (gfc_omp_namelist *list = code->ext.omp_clauses->lists;
+	   list; list = list->next)
+	if (list->clause == OMP_LIST_REDUCTION
+	    || list->clause == OMP_LIST_REDUCTION_INSCAN
+	    || list->clause == OMP_LIST_REDUCTION_TASK)
+	  {
+	    if (mask & GFC_OMP_MASK_TEAMS)
+	      *gfc_omp_get_nm_ref (&clausesa[GFC_OMP_SPLIT_TEAMS], list->clause)
+		= list->item;
+	    if (mask & GFC_OMP_MASK_PARALLEL)
+	      *gfc_omp_get_nm_ref (&clausesa[GFC_OMP_SPLIT_PARALLEL],
+				   list->clause) = list->item;
+	    else if (mask & GFC_OMP_MASK_DO)
+	      *gfc_omp_get_nm_ref (&clausesa[GFC_OMP_SPLIT_DO], list->clause)
+		= list->item;
+	    if (mask & GFC_OMP_MASK_SIMD)
+	      *gfc_omp_get_nm_ref (&clausesa[GFC_OMP_SPLIT_SIMD], list->clause)
+		= list->item;
+	  }
       if (mask & GFC_OMP_MASK_TARGET)
-	clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IN_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TARGET],
+			       code->ext.omp_clauses, OMP_LIST_IN_REDUCTION);
       if (mask & GFC_OMP_MASK_TASKLOOP)
-	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_IN_REDUCTION]
-	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
+	gfc_copy_list_clauses (&clausesa[GFC_OMP_SPLIT_TASKLOOP],
+				 code->ext.omp_clauses, OMP_LIST_IN_REDUCTION);
       /* Linear clause is supported on do and simd,
 	 put it on the innermost one.  */
-      clausesa[innermost].lists[OMP_LIST_LINEAR]
-	= code->ext.omp_clauses->lists[OMP_LIST_LINEAR];
+      gfc_copy_list_clauses (&clausesa[innermost],
+			     code->ext.omp_clauses, OMP_LIST_LINEAR);
     }
   if ((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
       == (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
     clausesa[GFC_OMP_SPLIT_DO].nowait = true;
+  return true;
+}
+
+static void
+gfc_trans_omp_free_clausea (gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM])
+{
+  gfc_omp_namelist *next, *list;
+  for (int i = 0; i < GFC_OMP_SPLIT_NUM; ++i)
+    for (list = clausesa[i].lists; list; list = next)
+      {
+	next = list->next;
+	free (list);
+      }
 }
 
 static tree
@@ -5273,6 +5313,7 @@  gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock,
   stmtblock_t block;
   gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
   tree stmt, body, omp_do_clauses = NULL_TREE;
+  bool do_free = false;
 
   if (pblock == NULL)
     gfc_start_block (&block);
@@ -5282,7 +5323,7 @@  gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock,
   if (clausesa == NULL)
     {
       clausesa = clausesa_buf;
-      gfc_split_omp_clauses (code, clausesa);
+      do_free = gfc_split_omp_clauses (code, clausesa);
     }
   if (flag_openmp)
     omp_do_clauses
@@ -5308,6 +5349,8 @@  gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock,
   else
     stmt = body;
   gfc_add_expr_to_block (&block, stmt);
+  if (clausesa == clausesa_buf && do_free)
+    gfc_trans_omp_free_clausea (clausesa_buf);
   return gfc_finish_block (&block);
 }
 
@@ -5318,6 +5361,7 @@  gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
   stmtblock_t block, *new_pblock = pblock;
   gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
   tree stmt, omp_clauses = NULL_TREE;
+  bool do_free = false;
 
   if (pblock == NULL)
     gfc_start_block (&block);
@@ -5327,7 +5371,7 @@  gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
   if (clausesa == NULL)
     {
       clausesa = clausesa_buf;
-      gfc_split_omp_clauses (code, clausesa);
+      do_free = gfc_split_omp_clauses (code, clausesa);
     }
   omp_clauses
     = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
@@ -5355,6 +5399,8 @@  gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
 		     void_type_node, stmt, omp_clauses);
   OMP_PARALLEL_COMBINED (stmt) = 1;
   gfc_add_expr_to_block (&block, stmt);
+  if (clausesa == clausesa_buf && do_free)
+    gfc_trans_omp_free_clausea (clausesa_buf);
   return gfc_finish_block (&block);
 }
 
@@ -5365,6 +5411,7 @@  gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock,
   stmtblock_t block;
   gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
   tree stmt, omp_clauses = NULL_TREE;
+  bool do_free = false;
 
   if (pblock == NULL)
     gfc_start_block (&block);
@@ -5374,7 +5421,7 @@  gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock,
   if (clausesa == NULL)
     {
       clausesa = clausesa_buf;
-      gfc_split_omp_clauses (code, clausesa);
+      do_free = gfc_split_omp_clauses (code, clausesa);
     }
   if (flag_openmp)
     omp_clauses
@@ -5399,6 +5446,8 @@  gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock,
       OMP_PARALLEL_COMBINED (stmt) = 1;
     }
   gfc_add_expr_to_block (&block, stmt);
+  if (clausesa == clausesa_buf && do_free)
+    gfc_trans_omp_free_clausea (clausesa_buf);
   return gfc_finish_block (&block);
 }
 
@@ -5456,7 +5505,7 @@  gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
 {
   stmtblock_t block, body;
   tree omp_clauses, stmt;
-  bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
+  bool has_lastprivate = !!gfc_omp_get_nm_list (clauses, OMP_LIST_LASTPRIVATE);
   location_t loc = gfc_get_location (&code->loc);
 
   gfc_start_block (&block);
@@ -5543,12 +5592,13 @@  gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa)
   stmtblock_t block;
   gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
   tree stmt, omp_clauses = NULL_TREE;
+  bool do_free = false;
 
   gfc_start_block (&block);
   if (clausesa == NULL)
     {
       clausesa = clausesa_buf;
-      gfc_split_omp_clauses (code, clausesa);
+      do_free = gfc_split_omp_clauses (code, clausesa);
     }
   if (flag_openmp)
     omp_clauses
@@ -5602,6 +5652,8 @@  gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa)
       stmt = distribute;
     }
   gfc_add_expr_to_block (&block, stmt);
+  if (clausesa == clausesa_buf && do_free)
+    gfc_trans_omp_free_clausea (clausesa_buf);
   return gfc_finish_block (&block);
 }
 
@@ -5613,12 +5665,13 @@  gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa,
   gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
   tree stmt;
   bool combined = true;
+  bool do_free = false;
 
   gfc_start_block (&block);
   if (clausesa == NULL)
     {
       clausesa = clausesa_buf;
-      gfc_split_omp_clauses (code, clausesa);
+      do_free = gfc_split_omp_clauses (code, clausesa);
     }
   if (flag_openmp)
     {
@@ -5655,6 +5708,8 @@  gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa,
 	OMP_TEAMS_COMBINED (stmt) = 1;
     }
   gfc_add_expr_to_block (&block, stmt);
+  if (clausesa == clausesa_buf && do_free)
+    gfc_trans_omp_free_clausea (clausesa_buf);
   return gfc_finish_block (&block);
 }
 
@@ -5664,9 +5719,10 @@  gfc_trans_omp_target (gfc_code *code)
   stmtblock_t block;
   gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
   tree stmt, omp_clauses = NULL_TREE;
+  bool do_free = false;
 
   gfc_start_block (&block);
-  gfc_split_omp_clauses (code, clausesa);
+  do_free = gfc_split_omp_clauses (code, clausesa);
   if (flag_openmp)
     omp_clauses
       = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TARGET],
@@ -5760,6 +5816,8 @@  gfc_trans_omp_target (gfc_code *code)
       cfun->has_omp_target = true;
     }
   gfc_add_expr_to_block (&block, stmt);
+  if (do_free)
+    gfc_trans_omp_free_clausea (clausesa);
   return gfc_finish_block (&block);
 }
 
@@ -5769,9 +5827,10 @@  gfc_trans_omp_taskloop (gfc_code *code)
   stmtblock_t block;
   gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
   tree stmt, omp_clauses = NULL_TREE;
+  bool do_free = false;
 
   gfc_start_block (&block);
-  gfc_split_omp_clauses (code, clausesa);
+  do_free = gfc_split_omp_clauses (code, clausesa);
   if (flag_openmp)
     omp_clauses
       = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TASKLOOP],
@@ -5802,6 +5861,8 @@  gfc_trans_omp_taskloop (gfc_code *code)
       stmt = taskloop;
     }
   gfc_add_expr_to_block (&block, stmt);
+  if (do_free)
+    gfc_trans_omp_free_clausea (clausesa);
   return gfc_finish_block (&block);
 }
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90 b/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90
index 956349204f4..72acb982a68 100644
--- a/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90
@@ -146,5 +146,6 @@  end subroutine test
 ! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. tile.2, 3" 2 "gimple" } }
 ! { dg-final { scan-tree-dump-times "acc loop private.i. independent" 2 "gimple" } }
 ! { dg-final { scan-tree-dump-times "private.z" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "omp target oacc_\[^ \]+ map.tofrom:y" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. reduction..:y." 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_parallel reduction..:y. map.tofrom:y" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_kernels map.tofrom:y" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop reduction..:y. private.i." 2 "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95 b/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95
index 4d40998958c..d083c7b6762 100644
--- a/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95
@@ -16,7 +16,7 @@  subroutine foo ()
 end subroutine
 
 ! { dg-final { scan-tree-dump-times "target oacc_parallel reduction..:a. map.tofrom.a." 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.p. reduction..:a." 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop reduction..:a. private.p." 1 "gimple" } }
 ! { dg-final { scan-tree-dump-times "target oacc_kernels map.force_tofrom:a .len: 4.." 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.k. reduction..:a." 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop reduction..:a. private.k." 1 "gimple" } }
 
diff --git a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90
index 361e0dad343..0f2425ae98a 100644
--- a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90
@@ -49,9 +49,9 @@  subroutine bar(n, m, u)
 end
 
 
-! { dg-final { scan-tree-dump-times "#pragma omp teams firstprivate\\(a1\\) firstprivate\\(b1\\) shared\\(u\\) default\\(none\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp teams shared\\(u\\) firstprivate\\(a1\\) firstprivate\\(b1\\) default\\(none\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp distribute lastprivate\\(d1\\)" 1 "original" } }
-! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(a1\\) firstprivate\\(b1\\) lastprivate\\(d1\\) shared\\(u\\) default\\(none\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel shared\\(u\\) firstprivate\\(a1\\) firstprivate\\(b1\\) lastprivate\\(d1\\) default\\(none\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp simd lastprivate\\(d1\\)" 1 "original" } }
 
diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction4.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
index af8c91b2a87..0a10ecf4d80 100644
--- a/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/reduction4.f90
@@ -155,9 +155,9 @@  end
 ! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(inscan,\\\+:a\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp for reduction\\(task,\\\+:a\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\n\r\]" 8 "original" } }
-! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(\\\+:a\\)" 2 "original" } }
-! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(inscan,\\\+:a\\)" 1 "original" } }
-! { dg-final { scan-tree-dump-times "#pragma omp parallel private\\(i\\) reduction\\(task,\\\+:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel reduction\\(\\\+:a\\) private\\(i\\)" 2 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel reduction\\(inscan,\\\+:a\\) private\\(i\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel reduction\\(task,\\\+:a\\) private\\(i\\)" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp section\[\n\r\]" 4 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(\\\+:a\\)" 2 "original" } }
 ! { dg-final { scan-tree-dump-times "#pragma omp sections reduction\\(inscan,\\\+:a\\)" 1 "original" } }