The 'no_openmp_constructs' assumption clause came up in a
potential performance improvement discussion and it makes
sense to permit users as early as possible to add such hints,
which can help the compiler. (For now, most assumption clauses
are ignored, except for 'holds' in an executable context; but
more might get used in the future.)

When doing the trivial change, I got odd error messages due
to partial matches of no_openmp... stating that I had
duplicated 'no_openmp' - which was purely due to partial
matches. This is now much improved (for free-form Fortran
at least) by printing a proper diagnostic and always requiring
some separator; before, in some cases it was missed. Additionally,
it avoids manual handling in most cases. [Care has been taken
such that fixed-form Fortran is not broken, albeit it is less
tested.]

Committed the attached patch as r16-6250-g4d6a43726148db.

Tobias
commit 4d6a43726148dbb2eff916de375af6003eacf8c9
Author: Tobias Burnus <[email protected]>
Date:   Thu Dec 18 22:55:40 2025 +0100

    OpenMP: Add no_openmp_constructs; improve Fortran clause parsing
    
    Add the assumption clause 'no_openmp_constructs' (which as most assumption
    clauses is ignored in the front end - for now).
    For Fortran, improve free-form parsing of argument-free clauses
    by avoiding substring matches.
    
    gcc/c/ChangeLog:
    
            * c-parser.cc (c_parser_omp_assumption_clauses): Add
            no_openmp_constructs clause.
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_omp_assumption_clauses): Add
            no_openmp_constructs clause.
    
    gcc/fortran/ChangeLog:
    
            * dump-parse-tree.cc (show_omp_assumes): Handle
            no_openmp_constructs clause.
            * gfortran.h (struct gfc_omp_assumptions): Add
            no_openmp_constructs.
            * openmp.cc (gfc_match_dupl_check): For free-form
            Fortran, avoid substring matching.
            (gfc_match_omp_clauses): Match no_openmp_constructs clause.
            Remove no longer needed 'needs_space', match 'order' followed by
            parenthesis instead of 'order' with parenthesis; reorder 'order'
            and 'ordering' clauses for free-form Fortran.
            (gfc_match_omp_assumes): Handle no_openmp_constructs clause.
    
    libgomp/ChangeLog:
    
            * libgomp.texi (OpenMP Implemenation Status): Mark
            no_openmp_constructs as implemented.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/goacc/update-if_present-2.f90: Update dg-error.
            * gfortran.dg/gomp/order-8.f90: Likewise.
            * gfortran.dg/gomp/order-9.f90: Likewise.
            * c-c++-common/gomp/assume-5.c: New test.
            * gfortran.dg/gomp/assume-6.f90: New test.
---
 gcc/c/c-parser.cc                                  |  17 ++-
 gcc/cp/parser.cc                                   |  17 ++-
 gcc/fortran/dump-parse-tree.cc                     |   2 +
 gcc/fortran/gfortran.h                             |   3 +-
 gcc/fortran/openmp.cc                              | 130 ++++++++++-----------
 gcc/testsuite/c-c++-common/gomp/assume-5.c         |  18 +++
 .../gfortran.dg/goacc/update-if_present-2.f90      |  12 +-
 gcc/testsuite/gfortran.dg/gomp/assume-6.f90        |   8 ++
 gcc/testsuite/gfortran.dg/gomp/order-8.f90         |   4 +-
 gcc/testsuite/gfortran.dg/gomp/order-9.f90         |  16 +--
 libgomp/libgomp.texi                               |   2 +-
 11 files changed, 138 insertions(+), 91 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index d6d0b0ed415..e39429afbb5 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -30172,19 +30172,23 @@ c_parser_omp_error (c_parser *parser, enum pragma_context context)
   return false;
 }
 
-/* Assumption clauses:
-   OpenMP 5.1
+/* Assumption clauses
+   OpenMP 5.1:
    absent (directive-name-list)
    contains (directive-name-list)
    holds (expression)
    no_openmp
    no_openmp_routines
-   no_parallelism  */
+   no_parallelism
+
+   OpenMP 6.0:
+   no_openmp_constructs  */
 
 static void
 c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
 {
   bool no_openmp = false;
+  bool no_openmp_constructs = false;
   bool no_openmp_routines = false;
   bool no_parallelism = false;
   bitmap_head absent_head, contains_head;
@@ -30217,6 +30221,13 @@ c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
 	    error_at (cloc, "too many %qs clauses", "no_openmp");
 	  no_openmp = true;
 	}
+      else if (!strcmp (p, "no_openmp_constructs"))
+	{
+	  c_parser_consume_token (parser);
+	  if (no_openmp_constructs)
+	    error_at (cloc, "too many %qs clauses", "no_openmp_constructs");
+	  no_openmp_constructs = true;
+	}
       else if (!strcmp (p, "no_openmp_routines"))
 	{
 	  c_parser_consume_token (parser);
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 521c05549f1..284fd9a534b 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -51959,20 +51959,24 @@ cp_parser_omp_context_selector_specification (cp_parser *parser,
   return nreverse (ret);
 }
 
-/* Assumption clauses:
-   OpenMP 5.1
+/* Assumption clauses
+   OpenMP 5.1:
    absent (directive-name-list)
    contains (directive-name-list)
    holds (expression)
    no_openmp
    no_openmp_routines
-   no_parallelism  */
+   no_parallelism
+
+   OpenMP 6.0:
+   no_openmp_constructs  */
 
 static void
 cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
 				  bool is_assume)
 {
   bool no_openmp = false;
+  bool no_openmp_constructs = false;
   bool no_openmp_routines = false;
   bool no_parallelism = false;
   bitmap_head absent_head, contains_head;
@@ -52005,6 +52009,13 @@ cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
 	    error_at (cloc, "too many %qs clauses", "no_openmp");
 	  no_openmp = true;
 	}
+      else if (!strcmp (p, "no_openmp_constructs"))
+	{
+	  cp_lexer_consume_token (parser->lexer);
+	  if (no_openmp_constructs)
+	    error_at (cloc, "too many %qs clauses", "no_openmp_constructs");
+	  no_openmp_constructs = true;
+	}
       else if (!strcmp (p, "no_openmp_routines"))
 	{
 	  cp_lexer_consume_token (parser->lexer);
diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc
index db6d54f5fc7..b081bbfc135 100644
--- a/gcc/fortran/dump-parse-tree.cc
+++ b/gcc/fortran/dump-parse-tree.cc
@@ -1736,6 +1736,8 @@ show_omp_assumes (gfc_omp_assumptions *assume)
     }
   if (assume->no_openmp)
     fputs (" NO_OPENMP", dumpfile);
+  if (assume->no_openmp_constructs)
+    fputs (" NO_OPENMP_CONSTRUCTS", dumpfile);
   if (assume->no_openmp_routines)
     fputs (" NO_OPENMP_ROUTINES", dumpfile);
   if (assume->no_parallelism)
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 72aecfb8379..da007c9ca87 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1631,7 +1631,8 @@ typedef struct gfc_omp_assumptions
   int n_absent, n_contains;
   enum gfc_statement *absent, *contains;
   gfc_expr_list *holds;
-  bool no_openmp:1, no_openmp_routines:1, no_parallelism:1;
+  bool no_openmp:1, no_openmp_routines:1, no_openmp_constructs:1;
+  bool no_parallelism:1;
 }
 gfc_omp_assumptions;
 
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 4527068f974..a7a76694c2c 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -2313,9 +2313,18 @@ gfc_match_dupl_check (bool not_dupl, const char *name, bool open_parens = false,
 		      gfc_expr **expr = NULL, const char *dupl_msg = NULL)
 {
   match m;
+  char c;
   locus old_loc = gfc_current_locus;
   if ((m = gfc_match (name)) != MATCH_YES)
     return m;
+  /* Ensure that no partial string is matched.  */
+  if (gfc_current_form == FORM_FREE
+      && gfc_match_eos () != MATCH_YES
+      && ((c = gfc_peek_ascii_char ()) == '_' || ISALNUM (c)))
+    {
+      gfc_current_locus = old_loc;
+      return MATCH_NO;
+    }
   if (!not_dupl)
     {
       if (dupl_msg)
@@ -2442,7 +2451,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->memorder = OMP_MEMORDER_ACQ_REL;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_MEMORDER)
@@ -2453,7 +2461,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->memorder = OMP_MEMORDER_ACQUIRE;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_AFFINITY)
@@ -2574,7 +2581,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 					     gfc_default_integer_kind,
 					     &gfc_current_locus);
 		  mpz_set_si (c->async_expr->value.integer, GOMP_ASYNC_NOVAL);
-		  needs_space = true;
 		}
 	      continue;
 	    }
@@ -2585,7 +2591,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->par_auto = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_ATTACH)
@@ -2625,7 +2630,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->capture = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if (mask & OMP_CLAUSE_COLLAPSE)
@@ -2657,7 +2661,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->compare = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_ASSUMPTIONS)
@@ -3198,7 +3201,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->finalize = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
@@ -3215,7 +3217,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->full = needs_space = true;
+	      c->full = true;
 	      continue;
 	    }
 	  break;
@@ -3232,8 +3234,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		  gfc_current_locus = old_loc;
 		  break;
 		}
-	      else if (m == MATCH_NO)
-		needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_GRAINSIZE)
@@ -3292,7 +3292,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->if_present = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_IF)
@@ -3337,7 +3336,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->inbranch = needs_space = true;
+	      c->inbranch = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_INDEPENDENT)
@@ -3347,7 +3346,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->independent = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_INDIRECT)
@@ -3735,7 +3733,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->mergeable = needs_space = true;
+	      c->mergeable = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_MESSAGE)
@@ -3754,39 +3752,51 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 					   OMP_MAP_IF_PRESENT, true,
 					   allow_derived))
 	    continue;
+	  if ((mask & OMP_CLAUSE_ASSUMPTIONS)
+	      && (m = gfc_match_dupl_check (!c->assume
+					    || !c->assume->no_openmp_constructs,
+					    "no_openmp_constructs")) != MATCH_NO)
+	    {
+	      if (m == MATCH_ERROR)
+		goto error;
+	      if (c->assume == NULL)
+		c->assume = gfc_get_omp_assumptions ();
+	      c->assume->no_openmp_constructs = true;
+	      continue;
+	    }
 	  if ((mask & OMP_CLAUSE_ASSUMPTIONS)
 	      && (m = gfc_match_dupl_check (!c->assume
 					    || !c->assume->no_openmp_routines,
-					    "no_openmp_routines")) == MATCH_YES)
+					    "no_openmp_routines")) != MATCH_NO)
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
 	      if (c->assume == NULL)
 		c->assume = gfc_get_omp_assumptions ();
-	      c->assume->no_openmp_routines = needs_space = true;
+	      c->assume->no_openmp_routines = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_ASSUMPTIONS)
 	      && (m = gfc_match_dupl_check (!c->assume || !c->assume->no_openmp,
-					    "no_openmp")) == MATCH_YES)
+					    "no_openmp")) != MATCH_NO)
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
 	      if (c->assume == NULL)
 		c->assume = gfc_get_omp_assumptions ();
-	      c->assume->no_openmp = needs_space = true;
+	      c->assume->no_openmp = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_ASSUMPTIONS)
 	      && (m = gfc_match_dupl_check (!c->assume
 					    || !c->assume->no_parallelism,
-					    "no_parallelism")) == MATCH_YES)
+					    "no_parallelism")) != MATCH_NO)
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
 	      if (c->assume == NULL)
 		c->assume = gfc_get_omp_assumptions ();
-	      c->assume->no_parallelism = needs_space = true;
+	      c->assume->no_parallelism = true;
 	      continue;
 	    }
 
@@ -3814,7 +3824,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->nogroup = needs_space = true;
+	      c->nogroup = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_NOHOST)
@@ -3822,7 +3832,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->nohost = needs_space = true;
+	      c->nohost = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_NOTEMPORAL)
@@ -3836,7 +3846,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->notinbranch = needs_space = true;
+	      c->notinbranch = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_NOWAIT)
@@ -3844,7 +3854,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->nowait = needs_space = true;
+	      c->nowait = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_NUM_GANGS)
@@ -3907,28 +3917,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    }
 	  break;
 	case 'o':
-	  if ((mask & OMP_CLAUSE_ORDER)
-	      && (m = gfc_match_dupl_check (!c->order_concurrent, "order ("))
-		 != MATCH_NO)
-	    {
-	      if (m == MATCH_ERROR)
-		goto error;
-	      if (gfc_match (" reproducible : concurrent )") == MATCH_YES)
-		c->order_reproducible = true;
-	      else if (gfc_match (" concurrent )") == MATCH_YES)
-		;
-	      else if (gfc_match (" unconstrained : concurrent )") == MATCH_YES)
-		c->order_unconstrained = true;
-	      else
-		{
-		  gfc_error ("Expected ORDER(CONCURRENT) at %C "
-			     "with optional %<reproducible%> or "
-			     "%<unconstrained%> modifier");
-		  goto error;
-		}
-	      c->order_concurrent = true;
-	      continue;
-	    }
 	  if ((mask & OMP_CLAUSE_ORDERED)
 	      && (m = gfc_match_dupl_check (!c->ordered, "ordered"))
 		 != MATCH_NO)
@@ -3955,7 +3943,28 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		  continue;
 		}
 
-	      needs_space = true;
+	      continue;
+	    }
+	  if ((mask & OMP_CLAUSE_ORDER)
+	      && (m = gfc_match_dupl_check (!c->order_concurrent, "order", true))
+		 != MATCH_NO)
+	    {
+	      if (m == MATCH_ERROR)
+		goto error;
+	      if (gfc_match (" reproducible : concurrent )") == MATCH_YES)
+		c->order_reproducible = true;
+	      else if (gfc_match (" concurrent )") == MATCH_YES)
+		;
+	      else if (gfc_match (" unconstrained : concurrent )") == MATCH_YES)
+		c->order_unconstrained = true;
+	      else
+		{
+		  gfc_error ("Expected ORDER(CONCURRENT) at %C "
+			     "with optional %<reproducible%> or "
+			     "%<unconstrained%> modifier");
+		  goto error;
+		}
+	      c->order_concurrent = true;
 	      continue;
 	    }
 	  break;
@@ -4080,7 +4089,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->atomic_op = GFC_OMP_ATOMIC_READ;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_REDUCTION)
@@ -4095,7 +4103,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->memorder = OMP_MEMORDER_RELAXED;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_MEMORDER)
@@ -4106,7 +4113,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->memorder = OMP_MEMORDER_RELEASE;
-	      needs_space = true;
 	      continue;
 	    }
 	  break;
@@ -4200,11 +4206,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 		  break;
 		}
 	      else if (m == MATCH_NO)
-		{
-		  c->self_expr = gfc_get_logical_expr (gfc_default_logical_kind,
-						       NULL, true);
-		  needs_space = true;
-		}
+		c->self_expr = gfc_get_logical_expr (gfc_default_logical_kind,
+						     NULL, true);
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_SELF)
@@ -4220,7 +4223,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->seq = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_MEMORDER)
@@ -4231,7 +4233,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->memorder = OMP_MEMORDER_SEQ_CST;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_SHARED)
@@ -4252,7 +4253,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->simd = needs_space = true;
+	      c->simd = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_SEVERITY)
@@ -4308,7 +4309,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->threads = needs_space = true;
+	      c->threads = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_TILE)
@@ -4348,7 +4349,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	    {
 	      if (m == MATCH_ERROR)
 		goto error;
-	      c->untied = needs_space = true;
+	      c->untied = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_ATOMIC)
@@ -4359,7 +4360,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->atomic_op = GFC_OMP_ATOMIC_UPDATE;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_USE)
@@ -4412,8 +4412,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      m = match_oacc_clause_gwv (c, GOMP_DIM_VECTOR);
 	      if (m == MATCH_ERROR)
 		goto error;
-	      if (m == MATCH_NO)
-		needs_space = true;
 	      continue;
 	    }
 	  break;
@@ -4447,7 +4445,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->weak = true;
-	      needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_WORKER)
@@ -4459,8 +4456,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      m = match_oacc_clause_gwv (c, GOMP_DIM_WORKER);
 	      if (m == MATCH_ERROR)
 		goto error;
-	      else if (m == MATCH_NO)
-		needs_space = true;
 	      continue;
 	    }
 	  if ((mask & OMP_CLAUSE_ATOMIC)
@@ -4471,7 +4466,6 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 	      if (m == MATCH_ERROR)
 		goto error;
 	      c->atomic_op = GFC_OMP_ATOMIC_WRITE;
-	      needs_space = true;
 	      continue;
 	    }
 	  break;
@@ -5356,6 +5350,8 @@ gfc_match_omp_assumes (void)
       gfc_current_ns->omp_assumes->no_openmp |= c->assume->no_openmp;
       gfc_current_ns->omp_assumes->no_openmp_routines
 	|= c->assume->no_openmp_routines;
+      gfc_current_ns->omp_assumes->no_openmp_constructs
+	|= c->assume->no_openmp_constructs;
       gfc_current_ns->omp_assumes->no_parallelism |= c->assume->no_parallelism;
       if (gfc_current_ns->omp_assumes->holds && c->assume->holds)
 	{
diff --git a/gcc/testsuite/c-c++-common/gomp/assume-5.c b/gcc/testsuite/c-c++-common/gomp/assume-5.c
new file mode 100644
index 00000000000..6ffb0148fcc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/assume-5.c
@@ -0,0 +1,18 @@
+#pragma omp assumes no_openmp_constructs
+
+#pragma omp begin assumes no_openmp_constructs no_parallelism
+void g(int x)
+{
+    if (x <= 0)
+      return;
+}
+#pragma omp end assumes
+
+void f()
+{
+  #pragma omp assume no_openmp no_openmp_something  // { dg-error "32: expected assumption clause" }
+    ;
+
+  #pragma omp assume no_openmp no_openmp_routines no_openmp_constructs no_openmp_constructs // { dg-error "72: too many 'no_openmp_constructs' clauses" }
+    ;
+}
diff --git a/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90 b/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90
index 052d2abe888..41c2657b536 100644
--- a/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90
@@ -12,10 +12,10 @@ subroutine t1
 
   allocate (x, y, z(100))
 
-  !$acc enter data copyin(a) if_present ! { dg-error "Expected '\\(' after 'if'" }
-  !$acc exit data copyout(a) if_present ! { dg-error "Expected '\\(' after 'if'" }
+  !$acc enter data copyin(a) if_present ! { dg-error "Failed to match clause" }
+  !$acc exit data copyout(a) if_present ! { dg-error "Failed to match clause" }
 
-  !$acc data copy(a) if_present ! { dg-error "Expected '\\(' after 'if'" }
+  !$acc data copy(a) if_present ! { dg-error "Failed to match clause" }
   !$acc end data ! { dg-error "Unexpected ..ACC END DATA statement" }
 
   !$acc declare link(a) if_present ! { dg-error "Unexpected junk after" }
@@ -40,17 +40,17 @@ subroutine t2
   end do
   !$acc end parallel
 
-  !$acc kernels loop if_present ! { dg-error "Expected '\\(' after 'if'" }
+  !$acc kernels loop if_present ! { dg-error "Failed to match clause" }
   do b = 1, 10
   end do
   !$acc end kernels loop ! { dg-error "Unexpected ..ACC END KERNELS LOOP statement" }
 
-  !$acc parallel loop if_present ! { dg-error "Expected '\\(' after 'if'" }
+  !$acc parallel loop if_present ! { dg-error "Failed to match clause" }
   do b = 1, 10
   end do
   !$acc end parallel loop   ! { dg-error "Unexpected ..ACC END PARALLEL LOOP statement" }
 
-  !$acc serial loop if_present ! { dg-error "Expected '\\(' after 'if'" }
+  !$acc serial loop if_present ! { dg-error "Failed to match clause" }
   do b = 1, 10
   end do
   !$acc end serial loop   ! { dg-error "Unexpected ..ACC END SERIAL LOOP statement" }
diff --git a/gcc/testsuite/gfortran.dg/gomp/assume-6.f90 b/gcc/testsuite/gfortran.dg/gomp/assume-6.f90
new file mode 100644
index 00000000000..80b746d6424
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/assume-6.f90
@@ -0,0 +1,8 @@
+!$omp assume no_openmp no_openmp_something  ! { dg-error "24: Failed to match clause" }
+block
+end block
+
+!$omp assume no_openmp no_openmp_routines no_openmp_constructs no_openmp_constructs ! { dg-error "63: Duplicated 'no_openmp_constructs' clause" }
+block
+end block
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/order-8.f90 b/gcc/testsuite/gfortran.dg/gomp/order-8.f90
index 37b138b09cb..5d01c89ac96 100644
--- a/gcc/testsuite/gfortran.dg/gomp/order-8.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/order-8.f90
@@ -2,11 +2,11 @@
 subroutine f1 (a)
   integer :: a(*)
   integer i
-  !$omp do order				! { dg-error "Failed to match clause" }
+  !$omp do order				! { dg-error "Expected '\\(' after 'order'" }
   do i = 1, 128
     a(i) = a(i) + 1
   end do
-  !$omp do simd order :			! { dg-error "Failed to match clause" }
+  !$omp do simd order :			! { dg-error "Expected '\\(' after 'order'" }
   do i = 1, 128
     a(i) = a(i) + 1
   end do
diff --git a/gcc/testsuite/gfortran.dg/gomp/order-9.f90 b/gcc/testsuite/gfortran.dg/gomp/order-9.f90
index c7695114cde..0604a263203 100644
--- a/gcc/testsuite/gfortran.dg/gomp/order-9.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/order-9.f90
@@ -1,34 +1,34 @@
 subroutine foo
-  !$omp do schedule(static) order(concurrent) order(concurrent) ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp do schedule(static) order(concurrent) order(concurrent) ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
-  !$omp do schedule(static) order(reproducible:concurrent) order(unconstrained:concurrent)      ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp do schedule(static) order(reproducible:concurrent) order(unconstrained:concurrent)      ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
 
-  !$omp loop bind(thread) order(concurrent) order(concurrent)    ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp loop bind(thread) order(concurrent) order(concurrent)    ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
-  !$omp loop bind(thread) order(reproducible:concurrent) order(unconstrained:concurrent) ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp loop bind(thread) order(reproducible:concurrent) order(unconstrained:concurrent) ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
-  !$omp simd order(concurrent) order(concurrent) ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp simd order(concurrent) order(concurrent) ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
-  !$omp simd order(reproducible:concurrent) order(unconstrained:concurrent)      ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp simd order(reproducible:concurrent) order(unconstrained:concurrent)      ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
-  !$omp distribute dist_schedule(static) order(concurrent) order(concurrent)     ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp distribute dist_schedule(static) order(concurrent) order(concurrent)     ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
-  !$omp loop bind(thread) order(reproducible:concurrent) order(unconstrained:concurrent) ! { dg-error "Duplicated 'order \\(' clause" }
+  !$omp loop bind(thread) order(reproducible:concurrent) order(unconstrained:concurrent) ! { dg-error "Duplicated 'order' clause" }
   do i = 1, 8
     call f0 ()
   end do
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index aabab4533f0..621d5588fb0 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -551,7 +551,7 @@ to address of matching mapped list item per 5.1, Sect. 2.21.7.2 @tab N @tab
 @item @code{message} and @code{severity} clauses to @code{parallel} directive
       @tab N @tab
 @item @code{self_maps} clause to @code{requires} directive @tab Y @tab
-@item @code{no_openmp_constructs} assumptions clause @tab N @tab
+@item @code{no_openmp_constructs} assumptions clause @tab Y @tab
 @item Restriction for @code{ordered} regarding loop-transforming directives
       @tab N @tab
 @item @code{apply} clause to loop-transforming constructs @tab N @tab

Reply via email to