diff mbox

Implement OpenMP 4.5 region/construct nesting rules

Message ID 20151106213205.GN5675@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 6, 2015, 9:32 p.m. UTC
Hi!

I've committed following patch, after reading through all the OpenMP 4.5
region/construct nesting rules.
Bootstrapped/regtested on x86_64-linux and i686-linux.

2015-11-06  Jakub Jelinek  <jakub@redhat.com>

	* gimplify.c (gimplify_omp_ordered): Fix up diagnostics
	wording.
	* omp-low.c (check_omp_nesting_restrictions): Update for the
	various new OpenMP 4.5 nesting restrictions, clarified
	nesting glossary, closely nested region relationship clarified
	to mean explicit or implicit parallel regions (target/teams),
	use %</%> or %qs where appropriate.

	* gcc.dg/gomp/ordered-2.c (f1): Expect an extra error.
	* g++.dg/gomp/ordered-2.C (f1): Likewise.
	* gfortran.dg/goacc/parallel-kernels-regions.f95: Adjust
	expected diagnostics for the addition of quotes.
	* gfortran.dg/gomp/target3.f90: Likewise.
	* c-c++-common/goacc/nesting-fail-1.c: Likewise.
	* c-c++-common/goacc-gomp/nesting-fail-1.c: Likewise.
	* c-c++-common/gomp/doacross-1.c: Likewise.
	* c-c++-common/gomp/nesting-warn-1.c: Likewise.
	* c-c++-common/gomp/cancel-1.c (f2): Add some new tests.
	Adjust expected diagnostics wording.
	* c-c++-common/gomp/clauses-4.c (foo): Likewise.
	Don't expect error on ordered threads simd when in for simd.
	* c-c++-common/gomp/nesting-2.c: New test.
	* c-c++-common/gomp/ordered-3.c (foo): Add some new tests.
	* c-c++-common/gomp/ordered-4.c: New test.


	Jakub
diff mbox

Patch

--- gcc/gimplify.c.jj	2015-11-06 08:08:07.000000000 +0100
+++ gcc/gimplify.c	2015-11-06 16:22:43.060530122 +0100
@@ -9259,9 +9259,9 @@  gimplify_omp_ordered (tree expr, gimple_
 	      || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
 	{
 	  error_at (OMP_CLAUSE_LOCATION (c),
-		    "%<depend%> clause must be closely nested "
-		    "inside a loop with %<ordered%> clause with "
-		    "a parameter");
+		    "%<ordered%> construct with %<depend%> clause must be "
+		    "closely nested inside a loop with %<ordered%> clause "
+		    "with a parameter");
 	  failures++;
 	}
       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
--- gcc/omp-low.c.jj	2015-11-06 08:07:57.000000000 +0100
+++ gcc/omp-low.c	2015-11-06 19:04:33.233408901 +0100
@@ -3112,9 +3112,9 @@  check_omp_nesting_restrictions (gimple *
   if (!(is_gimple_omp (stmt)
 	&& is_gimple_omp_oacc (stmt)))
     {
-      for (omp_context *ctx_ = ctx; ctx_ != NULL; ctx_ = ctx_->outer)
-	if (is_gimple_omp (ctx_->stmt)
-	    && is_gimple_omp_oacc (ctx_->stmt)
+      for (omp_context *octx = ctx; octx != NULL; octx = octx->outer)
+	if (is_gimple_omp (octx->stmt)
+	    && is_gimple_omp_oacc (octx->stmt)
 	    /* Except for atomic codes that we share with OpenMP.  */
 	    && ! (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
 		  || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE))
@@ -3134,12 +3134,27 @@  check_omp_nesting_restrictions (gimple *
 	  if (gimple_code (stmt) == GIMPLE_OMP_ORDERED)
 	    {
 	      c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
-	      if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD)
-		return true;
+	      if (find_omp_clause (c, OMP_CLAUSE_SIMD))
+		{
+		  if (find_omp_clause (c, OMP_CLAUSE_THREADS)
+		      && (ctx->outer == NULL
+			  || !gimple_omp_for_combined_into_p (ctx->stmt)
+			  || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR
+			  || (gimple_omp_for_kind (ctx->outer->stmt)
+			      != GF_OMP_FOR_KIND_FOR)
+			  || !gimple_omp_for_combined_p (ctx->outer->stmt)))
+		    {
+		      error_at (gimple_location (stmt),
+				"%<ordered simd threads%> must be closely "
+				"nested inside of %<for simd%> region");
+		      return false;
+		    }
+		  return true;
+		}
 	    }
 	  error_at (gimple_location (stmt),
 		    "OpenMP constructs other than %<#pragma omp ordered simd%>"
-		    " may not be nested inside simd region");
+		    " may not be nested inside %<simd%> region");
 	  return false;
 	}
       else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
@@ -3150,8 +3165,9 @@  check_omp_nesting_restrictions (gimple *
 	      && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
 	    {
 	      error_at (gimple_location (stmt),
-			"only distribute or parallel constructs are allowed to "
-			"be closely nested inside teams construct");
+			"only %<distribute%> or %<parallel%> regions are "
+			"allowed to be strictly nested inside %<teams%> "
+			"region");
 	      return false;
 	    }
 	}
@@ -3166,8 +3182,8 @@  check_omp_nesting_restrictions (gimple *
 	  if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
 	    {
 	      error_at (gimple_location (stmt),
-			"distribute construct must be closely nested inside "
-			"teams construct");
+			"%<distribute%> region must be strictly nested "
+			"inside %<teams%> construct");
 	      return false;
 	    }
 	  return true;
@@ -3222,13 +3238,15 @@  check_omp_nesting_restrictions (gimple *
 	{
 	  const char *bad = NULL;
 	  const char *kind = NULL;
+	  const char *construct
+	    = (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
+	       == BUILT_IN_GOMP_CANCEL)
+	      ? "#pragma omp cancel"
+	      : "#pragma omp cancellation point";
 	  if (ctx == NULL)
 	    {
 	      error_at (gimple_location (stmt), "orphaned %qs construct",
-			DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
-			== BUILT_IN_GOMP_CANCEL
-			? "#pragma omp cancel"
-			: "#pragma omp cancellation point");
+			construct);
 	      return false;
 	    }
 	  switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
@@ -3304,7 +3322,33 @@  check_omp_nesting_restrictions (gimple *
 	      if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
 		bad = "#pragma omp task";
 	      else
-		ctx->cancellable = true;
+		{
+		  for (omp_context *octx = ctx->outer;
+		       octx; octx = octx->outer)
+		    {
+		      switch (gimple_code (octx->stmt))
+			{
+			case GIMPLE_OMP_TASKGROUP:
+			  break;
+			case GIMPLE_OMP_TARGET:
+			  if (gimple_omp_target_kind (octx->stmt)
+			      != GF_OMP_TARGET_KIND_REGION)
+			    continue;
+			  /* FALLTHRU */
+			case GIMPLE_OMP_PARALLEL:
+			case GIMPLE_OMP_TEAMS:
+			  error_at (gimple_location (stmt),
+				    "%<%s taskgroup%> construct not closely "
+				    "nested inside of %<taskgroup%> region",
+				    construct);
+			  return false;
+			default:
+			  continue;
+			}
+		      break;
+		    }
+		  ctx->cancellable = true;
+		}
 	      kind = "taskgroup";
 	      break;
 	    default:
@@ -3315,10 +3359,7 @@  check_omp_nesting_restrictions (gimple *
 	    {
 	      error_at (gimple_location (stmt),
 			"%<%s %s%> construct not closely nested inside of %qs",
-			DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
-			== BUILT_IN_GOMP_CANCEL
-			? "#pragma omp cancel"
-			: "#pragma omp cancellation point", kind, bad);
+			construct, kind, bad);
 	      return false;
 	    }
 	}
@@ -3329,6 +3370,10 @@  check_omp_nesting_restrictions (gimple *
 	switch (gimple_code (ctx->stmt))
 	  {
 	  case GIMPLE_OMP_FOR:
+	    if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
+		&& gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
+	      break;
+	    /* FALLTHRU */
 	  case GIMPLE_OMP_SECTIONS:
 	  case GIMPLE_OMP_SINGLE:
 	  case GIMPLE_OMP_ORDERED:
@@ -3342,17 +3387,24 @@  check_omp_nesting_restrictions (gimple *
 		  return true;
 		error_at (gimple_location (stmt),
 			  "barrier region may not be closely nested inside "
-			  "of work-sharing, critical, ordered, master or "
-			  "explicit task region");
+			  "of work-sharing, %<critical%>, %<ordered%>, "
+			  "%<master%>, explicit %<task%> or %<taskloop%> "
+			  "region");
 		return false;
 	      }
 	    error_at (gimple_location (stmt),
 		      "work-sharing region may not be closely nested inside "
-		      "of work-sharing, critical, ordered, master or explicit "
-		      "task region");
+		      "of work-sharing, %<critical%>, %<ordered%>, "
+		      "%<master%>, explicit %<task%> or %<taskloop%> region");
 	    return false;
 	  case GIMPLE_OMP_PARALLEL:
+	  case GIMPLE_OMP_TEAMS:
 	    return true;
+	  case GIMPLE_OMP_TARGET:
+	    if (gimple_omp_target_kind (ctx->stmt)
+		== GF_OMP_TARGET_KIND_REGION)
+	      return true;
+	    break;
 	  default:
 	    break;
 	  }
@@ -3362,15 +3414,26 @@  check_omp_nesting_restrictions (gimple *
 	switch (gimple_code (ctx->stmt))
 	  {
 	  case GIMPLE_OMP_FOR:
+	    if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
+		&& gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
+	      break;
+	    /* FALLTHRU */
 	  case GIMPLE_OMP_SECTIONS:
 	  case GIMPLE_OMP_SINGLE:
 	  case GIMPLE_OMP_TASK:
 	    error_at (gimple_location (stmt),
-		      "master region may not be closely nested inside "
-		      "of work-sharing or explicit task region");
+		      "%<master%> region may not be closely nested inside "
+		      "of work-sharing, explicit %<task%> or %<taskloop%> "
+		      "region");
 	    return false;
 	  case GIMPLE_OMP_PARALLEL:
+	  case GIMPLE_OMP_TEAMS:
 	    return true;
+	  case GIMPLE_OMP_TARGET:
+	    if (gimple_omp_target_kind (ctx->stmt)
+		== GF_OMP_TARGET_KIND_REGION)
+	      return true;
+	    break;
 	  default:
 	    break;
 	  }
@@ -3395,8 +3458,7 @@  check_omp_nesting_restrictions (gimple *
 	  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
 	    {
 	      gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
-			  || (ctx == NULL
-			      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD));
+			  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD);
 	      continue;
 	    }
 	  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
@@ -3412,23 +3474,40 @@  check_omp_nesting_restrictions (gimple *
 					   OMP_CLAUSE_ORDERED)) == NULL_TREE)
 		{
 		  error_at (OMP_CLAUSE_LOCATION (c),
-			    "%<depend%> clause must be closely nested "
-			    "inside an ordered loop");
+			    "%<ordered%> construct with %<depend%> clause "
+			    "must be closely nested inside an %<ordered%> "
+			    "loop");
 		  return false;
 		}
 	      else if (OMP_CLAUSE_ORDERED_EXPR (oclause) == NULL_TREE)
 		{
 		  error_at (OMP_CLAUSE_LOCATION (c),
-			    "%<depend%> clause must be closely nested "
-			    "inside a loop with %<ordered%> clause with "
-			    "a parameter");
+			    "%<ordered%> construct with %<depend%> clause "
+			    "must be closely nested inside a loop with "
+			    "%<ordered%> clause with a parameter");
 		  return false;
 		}
 	    }
 	  else
 	    {
 	      error_at (OMP_CLAUSE_LOCATION (c),
-			"invalid depend kind in omp ordered depend");
+			"invalid depend kind in omp %<ordered%> %<depend%>");
+	      return false;
+	    }
+	}
+      c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
+      if (find_omp_clause (c, OMP_CLAUSE_SIMD))
+	{
+	  /* ordered simd must be closely nested inside of simd region,
+	     and simd region must not encounter constructs other than
+	     ordered simd, therefore ordered simd may be either orphaned,
+	     or ctx->stmt must be simd.  The latter case is handled already
+	     earlier.  */
+	  if (ctx != NULL)
+	    {
+	      error_at (gimple_location (stmt),
+			"%<ordered%> %<simd%> must be closely nested inside "
+			"%<simd%> region");
 	      return false;
 	    }
 	}
@@ -3437,24 +3516,35 @@  check_omp_nesting_restrictions (gimple *
 	  {
 	  case GIMPLE_OMP_CRITICAL:
 	  case GIMPLE_OMP_TASK:
+	  case GIMPLE_OMP_ORDERED:
+	  ordered_in_taskloop:
 	    error_at (gimple_location (stmt),
-		      "ordered region may not be closely nested inside "
-		      "of critical or explicit task region");
+		      "%<ordered%> region may not be closely nested inside "
+		      "of %<critical%>, %<ordered%>, explicit %<task%> or "
+		      "%<taskloop%> region");
 	    return false;
 	  case GIMPLE_OMP_FOR:
+	    if (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP)
+	      goto ordered_in_taskloop;
 	    if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
 				 OMP_CLAUSE_ORDERED) == NULL)
 	      {
 		error_at (gimple_location (stmt),
-			  "ordered region must be closely nested inside "
-			  "a loop region with an ordered clause");
+			  "%<ordered%> region must be closely nested inside "
+			  "a loop region with an %<ordered%> clause");
 		return false;
 	      }
 	    return true;
+	  case GIMPLE_OMP_TARGET:
+	    if (gimple_omp_target_kind (ctx->stmt)
+		!= GF_OMP_TARGET_KIND_REGION)
+	      break;
+	    /* FALLTHRU */
 	  case GIMPLE_OMP_PARALLEL:
+	  case GIMPLE_OMP_TEAMS:
 	    error_at (gimple_location (stmt),
-		      "ordered region must be closely nested inside "
-		      "a loop region with an ordered clause");
+		      "%<ordered%> region must be closely nested inside "
+		      "a loop region with an %<ordered%> clause");
 	    return false;
 	  default:
 	    break;
@@ -3470,8 +3560,8 @@  check_omp_nesting_restrictions (gimple *
 	    if (this_stmt_name == gimple_omp_critical_name (other_crit))
 	      {
 		error_at (gimple_location (stmt),
-			  "critical region may not be nested inside a critical "
-			  "region with the same name");
+			  "%<critical%> region may not be nested inside "
+			   "a %<critical%> region with the same name");
 		return false;
 	      }
       }
@@ -3482,8 +3572,8 @@  check_omp_nesting_restrictions (gimple *
 	  || gimple_omp_target_kind (ctx->stmt) != GF_OMP_TARGET_KIND_REGION)
 	{
 	  error_at (gimple_location (stmt),
-		    "teams construct not closely nested inside of target "
-		    "region");
+		    "%<teams%> construct not closely nested inside of "
+		    "%<target%> construct");
 	  return false;
 	}
       break;
@@ -3549,7 +3639,7 @@  check_omp_nesting_restrictions (gimple *
 	      != is_gimple_omp_oacc (ctx->stmt))
 	    {
 	      error_at (gimple_location (stmt),
-			"%s %s construct inside of %s %s region",
+			"%s %qs construct inside of %s %qs region",
 			(is_gimple_omp_oacc (stmt)
 			 ? "OpenACC" : "OpenMP"), stmt_name,
 			(is_gimple_omp_oacc (ctx->stmt)
@@ -3562,15 +3652,14 @@  check_omp_nesting_restrictions (gimple *
 	      if (is_gimple_omp_oacc (ctx->stmt))
 		{
 		  error_at (gimple_location (stmt),
-			    "%s construct inside of %s region",
+			    "%qs construct inside of %qs region",
 			    stmt_name, ctx_stmt_name);
 		  return false;
 		}
 	      else
 		{
-		  gcc_checking_assert (!is_gimple_omp_oacc (stmt));
 		  warning_at (gimple_location (stmt), 0,
-			      "%s construct inside of %s region",
+			      "%qs construct inside of %qs region",
 			      stmt_name, ctx_stmt_name);
 		}
 	    }
--- gcc/testsuite/gcc.dg/gomp/ordered-2.c.jj	2015-10-14 10:25:21.000000000 +0200
+++ gcc/testsuite/gcc.dg/gomp/ordered-2.c	2015-11-06 17:35:11.992932617 +0100
@@ -3,5 +3,5 @@ 
 void f1(void)
 {
   #pragma omp ordered asdf	/* { dg-error "expected" } */
-  #pragma omp ordered
+  #pragma omp ordered		/* { dg-error "region may not be closely nested inside of" } */
 }				/* { dg-error "expected expression" } */
--- gcc/testsuite/g++.dg/gomp/ordered-2.C.jj	2015-10-14 10:25:28.000000000 +0200
+++ gcc/testsuite/g++.dg/gomp/ordered-2.C	2015-11-06 18:17:53.872783499 +0100
@@ -3,5 +3,5 @@ 
 void f1(void)
 {
   #pragma omp ordered asdf	/* { dg-error "expected" } */
-  #pragma omp ordered
+  #pragma omp ordered		/* { dg-error "region may not be closely nested inside of" } */
 }				/* { dg-error "expected" } */
--- gcc/testsuite/gfortran.dg/goacc/parallel-kernels-regions.f95.jj	2015-10-14 10:25:11.000000000 +0200
+++ gcc/testsuite/gfortran.dg/goacc/parallel-kernels-regions.f95	2015-11-06 18:20:02.174999978 +0100
@@ -9,46 +9,46 @@  program test
   integer :: i
 
   !$acc parallel
-    !$acc kernels ! { dg-bogus "kernels construct inside of parallel region" "not implemented" { xfail *-*-* } }
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
     !$acc end kernels
   !$acc end parallel
 
   !$acc parallel
-    !$acc parallel ! { dg-bogus "parallel construct inside of parallel region" "not implemented" { xfail *-*-* } }
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
     !$acc end parallel
   !$acc end parallel
 
   !$acc parallel
-    !$acc parallel ! { dg-bogus "parallel construct inside of parallel region" "not implemented" { xfail *-*-* } }
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
     !$acc end parallel
-    !$acc kernels ! { dg-bogus "kernels construct inside of parallel region" "not implemented" { xfail *-*-* } }
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
     !$acc end kernels
   !$acc end parallel
 
   !$acc kernels
-    !$acc kernels ! { dg-bogus "kernels construct inside of kernels region" "not implemented" { xfail *-*-* } }
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
     !$acc end kernels
   !$acc end kernels
 
   !$acc kernels
-    !$acc parallel ! { dg-bogus "parallel construct inside of kernels region" "not implemented" { xfail *-*-* } }
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
     !$acc end parallel
   !$acc end kernels
 
   !$acc kernels
-    !$acc parallel ! { dg-bogus "parallel construct inside of kernels region" "not implemented" { xfail *-*-* } }
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
     !$acc end parallel
-    !$acc kernels ! { dg-bogus "kernels construct inside of kernels region" "not implemented" { xfail *-*-* } }
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
     !$acc end kernels
   !$acc end kernels
 
   !$acc parallel
-    !$acc data ! { dg-error "data construct inside of parallel region" }
+    !$acc data ! { dg-error ".data. construct inside of .parallel. region" }
     !$acc end data
   !$acc end parallel
 
   !$acc kernels
-    !$acc data ! { dg-error "data construct inside of kernels region" }
+    !$acc data ! { dg-error ".data. construct inside of .kernels. region" }
     !$acc end data
   !$acc end kernels
   
--- gcc/testsuite/gfortran.dg/gomp/target3.f90.jj	2015-10-14 10:25:11.000000000 +0200
+++ gcc/testsuite/gfortran.dg/gomp/target3.f90	2015-11-06 18:20:35.504536666 +0100
@@ -4,7 +4,7 @@ 
 subroutine foo (r)
   integer :: i, r
   !$omp target
-  !$omp target teams distribute parallel do reduction (+: r) ! { dg-warning "target construct inside of target region" }
+  !$omp target teams distribute parallel do reduction (+: r) ! { dg-warning ".target. construct inside of .target. region" }
     do i = 1, 10
       r = r + 1
     end do
--- gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c.jj	2015-10-14 10:25:30.000000000 +0200
+++ gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c	2015-11-06 17:39:58.504882344 +0100
@@ -7,15 +7,15 @@  f_acc_parallel (void)
 {
 #pragma acc parallel
   {
-#pragma acc parallel /* { dg-bogus "parallel construct inside of parallel region" "not implemented" { xfail *-*-* } } */
+#pragma acc parallel /* { dg-bogus ".parallel. construct inside of .parallel. region" "not implemented" { xfail *-*-* } } */
     ;
-#pragma acc kernels /* { dg-bogus "kernels construct inside of parallel region" "not implemented" { xfail *-*-* } } */
+#pragma acc kernels /* { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } } */
     ;
-#pragma acc data /* { dg-error "data construct inside of parallel region" } */
+#pragma acc data /* { dg-error ".data. construct inside of .parallel. region" } */
     ;
-#pragma acc update host(i) /* { dg-error "update construct inside of parallel region" } */
-#pragma acc enter data copyin(i) /* { dg-error "enter/exit data construct inside of parallel region" } */
-#pragma acc exit data delete(i) /* { dg-error "enter/exit data construct inside of parallel region" } */
+#pragma acc update host(i) /* { dg-error ".update. construct inside of .parallel. region" } */
+#pragma acc enter data copyin(i) /* { dg-error ".enter/exit data. construct inside of .parallel. region" } */
+#pragma acc exit data delete(i) /* { dg-error ".enter/exit data. construct inside of .parallel. region" } */
   }
 }
 
@@ -26,14 +26,14 @@  f_acc_kernels (void)
 {
 #pragma acc kernels
   {
-#pragma acc parallel /* { dg-bogus "parallel construct inside of kernels region" "not implemented" { xfail *-*-* } } */
+#pragma acc parallel /* { dg-bogus ".parallel. construct inside of .kernels. region" "not implemented" { xfail *-*-* } } */
     ;
-#pragma acc kernels /* { dg-bogus "kernels construct inside of kernels region" "not implemented" { xfail *-*-* } } */
+#pragma acc kernels /* { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } } */
     ;
-#pragma acc data /* { dg-error "data construct inside of kernels region" } */
+#pragma acc data /* { dg-error ".data. construct inside of .kernels. region" } */
     ;
-#pragma acc update host(i) /* { dg-error "update construct inside of kernels region" } */
-#pragma acc enter data copyin(i) /* { dg-error "enter/exit data construct inside of kernels region" } */
-#pragma acc exit data delete(i) /* { dg-error "enter/exit data construct inside of kernels region" } */
+#pragma acc update host(i) /* { dg-error ".update. construct inside of .kernels. region" } */
+#pragma acc enter data copyin(i) /* { dg-error ".enter/exit data. construct inside of .kernels. region" } */
+#pragma acc exit data delete(i) /* { dg-error ".enter/exit data. construct inside of .kernels. region" } */
   }
 }
--- gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c.jj	2015-11-05 11:39:52.000000000 +0100
+++ gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c	2015-11-06 21:14:46.000000000 +0100
@@ -151,15 +151,15 @@  f_omp (void)
 
 #pragma omp target
   {
-#pragma acc parallel /* { dg-error "OpenACC parallel construct inside of OpenMP target region" } */
+#pragma acc parallel /* { dg-error "OpenACC .parallel. construct inside of OpenMP .target. region" } */
     ;
-#pragma acc kernels /* { dg-error "OpenACC kernels construct inside of OpenMP target region" } */
+#pragma acc kernels /* { dg-error "OpenACC .kernels. construct inside of OpenMP .target. region" } */
     ;
-#pragma acc data /* { dg-error "OpenACC data construct inside of OpenMP target region" } */
+#pragma acc data /* { dg-error "OpenACC .data. construct inside of OpenMP .target. region" } */
     ;
-#pragma acc update host(i) /* { dg-error "OpenACC update construct inside of OpenMP target region" } */
-#pragma acc enter data copyin(i) /* { dg-error "OpenACC enter/exit data construct inside of OpenMP target region" } */
-#pragma acc exit data delete(i) /* { dg-error "OpenACC enter/exit data construct inside of OpenMP target region" } */
+#pragma acc update host(i) /* { dg-error "OpenACC .update. construct inside of OpenMP .target. region" } */
+#pragma acc enter data copyin(i) /* { dg-error "OpenACC .enter/exit data. construct inside of OpenMP .target. region" } */
+#pragma acc exit data delete(i) /* { dg-error "OpenACC .enter/exit data. construct inside of OpenMP .target. region" } */
 #pragma acc loop /* { dg-error "loop directive must be associated with an OpenACC compute region" } */
     for (i = 0; i < 2; ++i)
       ;
--- gcc/testsuite/c-c++-common/gomp/cancel-1.c.jj	2015-10-14 10:25:30.000000000 +0200
+++ gcc/testsuite/c-c++-common/gomp/cancel-1.c	2015-11-06 18:30:44.544959750 +0100
@@ -77,12 +77,73 @@  f2 (void)
       #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
       #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
       #pragma omp cancel sections		/* { dg-error "not closely nested inside" } */
+      #pragma omp cancel taskgroup		/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+      #pragma omp cancellation point parallel	/* { dg-error "not closely nested inside" } */
+      #pragma omp cancellation point for	/* { dg-error "not closely nested inside" } */
+      #pragma omp cancellation point sections	/* { dg-error "not closely nested inside" } */
+      #pragma omp cancellation point taskgroup	/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+    }
+    #pragma omp taskgroup
+    #pragma omp task
+    {
+      #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
+      #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
+      #pragma omp cancel sections		/* { dg-error "not closely nested inside" } */
       #pragma omp cancel taskgroup
       #pragma omp cancellation point parallel	/* { dg-error "not closely nested inside" } */
       #pragma omp cancellation point for	/* { dg-error "not closely nested inside" } */
       #pragma omp cancellation point sections	/* { dg-error "not closely nested inside" } */
       #pragma omp cancellation point taskgroup
     }
+    #pragma omp taskgroup
+    {
+      #pragma omp task
+      {
+	#pragma omp task
+	{
+	  #pragma omp cancellation point taskgroup
+	  #pragma omp cancel taskgroup
+	}
+      }
+    }
+    #pragma omp taskgroup
+    {
+      #pragma omp parallel
+      {
+	#pragma omp task
+	{
+	  #pragma omp cancel taskgroup		/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	  #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	}
+      }
+      #pragma omp target
+      {
+	#pragma omp task
+	{
+	  #pragma omp cancel taskgroup		/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	  #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	}
+      }
+      #pragma omp target
+      #pragma omp teams
+      #pragma omp distribute
+      for (i = 0; i < 10; i++)
+	{
+	  #pragma omp task
+	  {
+	    #pragma omp cancel taskgroup	/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	    #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	  }
+	}
+      #pragma omp target data map(i)
+      {
+	#pragma omp task
+	{
+	  #pragma omp cancel taskgroup
+	  #pragma omp cancellation point taskgroup
+	}
+      }
+    }
     #pragma omp for
     for (i = 0; i < 10; i++)
       {
@@ -179,14 +240,14 @@  f2 (void)
   }
   #pragma omp target teams
   {
-    #pragma omp cancel parallel			/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
-    #pragma omp cancel for			/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
-    #pragma omp cancel sections			/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
-    #pragma omp cancel taskgroup		/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
-    #pragma omp cancellation point parallel	/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
-    #pragma omp cancellation point for		/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
-    #pragma omp cancellation point sections	/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
-    #pragma omp cancellation point taskgroup	/* { dg-error "only distribute or parallel constructs are allowed to be closely nested" } */
+    #pragma omp cancel parallel			/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+    #pragma omp cancel for			/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+    #pragma omp cancel sections			/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+    #pragma omp cancel taskgroup		/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+    #pragma omp cancellation point parallel	/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+    #pragma omp cancellation point for		/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+    #pragma omp cancellation point sections	/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+    #pragma omp cancellation point taskgroup	/* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
   }
   #pragma omp target teams distribute
   for (i = 0; i < 10; i++)
--- gcc/testsuite/c-c++-common/gomp/clauses-4.c.jj	2015-10-14 10:25:30.000000000 +0200
+++ gcc/testsuite/c-c++-common/gomp/clauses-4.c	2015-11-06 17:46:55.157988821 +0100
@@ -57,40 +57,62 @@  foo (int y, short z)
   #pragma omp distribute parallel for ordered		/* { dg-error ".ordered. is not valid for .#pragma omp distribute parallel for." } */
   for (x = 0; x < 64; x++)
     {
-      #pragma omp ordered	/* { dg-error "ordered region must be closely nested inside a loop region with an ordered clause" } */
+      #pragma omp ordered	/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
       ;
     }
   #pragma omp target teams
   #pragma omp distribute parallel for simd ordered	/* { dg-error ".ordered. is not valid for .#pragma omp distribute parallel for simd." } */
   for (x = 0; x < 64; x++)
     {
-      #pragma omp ordered simd, threads	/* { dg-error "OpenMP constructs other than .#pragma omp ordered simd. may not be nested inside simd region" } */
+      #pragma omp ordered simd, threads
       ;
     }
   #pragma omp target
   #pragma omp teams distribute parallel for ordered		/* { dg-error ".ordered. is not valid for .#pragma omp teams distribute parallel for." } */
   for (x = 0; x < 64; x++)
     {
-      #pragma omp ordered	/* { dg-error "ordered region must be closely nested inside a loop region with an ordered clause" } */
+      #pragma omp ordered	/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
       ;
     }
   #pragma omp target
   #pragma omp teams distribute parallel for simd ordered	/* { dg-error ".ordered. is not valid for .#pragma omp teams distribute parallel for simd." } */
   for (x = 0; x < 64; x++)
     {
-      #pragma omp ordered simd, threads	/* { dg-error "OpenMP constructs other than .#pragma omp ordered simd. may not be nested inside simd region" } */
+      #pragma omp ordered simd, threads
       ;
     }
   #pragma omp target teams distribute parallel for ordered		/* { dg-error ".ordered. is not valid for .#pragma omp target teams distribute parallel for." } */
   for (x = 0; x < 64; x++)
     {
-      #pragma omp ordered	/* { dg-error "ordered region must be closely nested inside a loop region with an ordered clause" } */
+      #pragma omp ordered	/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
       ;
     }
   #pragma omp target teams distribute parallel for simd ordered	/* { dg-error ".ordered. is not valid for .#pragma omp target teams distribute parallel for simd." } */
   for (x = 0; x < 64; x++)
     {
-      #pragma omp ordered simd, threads	/* { dg-error "OpenMP constructs other than .#pragma omp ordered simd. may not be nested inside simd region" } */
+      #pragma omp ordered simd, threads
+      ;
+    }
+  #pragma omp simd
+  for (x = 0; x < 64; x++)
+    {
+      #pragma omp ordered threads simd		/* { dg-error ".ordered simd threads. must be closely nested inside of .for simd. region" } */
+      ;
+    }
+  #pragma omp for
+  for (x = 0; x < 64; x++)
+    {
+      #pragma omp simd
+      for (y = 0; y < 16; y++)
+	{
+	  #pragma omp ordered simd threads	/* { dg-error ".ordered simd threads. must be closely nested inside of .for simd. region" } */
+	  ;
+	}
+    }
+  #pragma omp for simd
+  for (x = 0; x < 64; x++)
+    {
+      #pragma omp ordered threads simd
       ;
     }
 }
--- gcc/testsuite/c-c++-common/gomp/doacross-1.c.jj	2015-10-14 10:25:30.000000000 +0200
+++ gcc/testsuite/c-c++-common/gomp/doacross-1.c	2015-11-06 17:32:49.254950430 +0100
@@ -32,8 +32,8 @@  foo (void)
 	  #pragma omp ordered depend (sink: i - 1, j - 2) /* { dg-error "does not match number" } */
 	  #pragma omp ordered depend (source)
 	}
-  #pragma omp ordered depend (sink: j)			/* { dg-error "clause must be closely nested inside an ordered loop" } */
-  #pragma omp ordered depend (source)			/* { dg-error "clause must be closely nested inside an ordered loop" } */
+  #pragma omp ordered depend (sink: j)			/* { dg-error "clause must be closely nested inside an .ordered. loop" } */
+  #pragma omp ordered depend (source)			/* { dg-error "clause must be closely nested inside an .ordered. loop" } */
   #pragma omp for ordered (1)
   for (i = 0; i < 64; i++)
     {
--- gcc/testsuite/c-c++-common/gomp/nesting-2.c.jj	2015-11-06 18:50:49.726005928 +0100
+++ gcc/testsuite/c-c++-common/gomp/nesting-2.c	2015-11-06 19:02:13.945370277 +0100
@@ -0,0 +1,154 @@ 
+void
+foo (void)
+{
+  int i;
+  #pragma omp taskloop
+  for (i = 0; i < 64; i++)
+    {
+      int j;
+      #pragma omp for			/* { dg-error "region may not be closely nested inside of" } */
+      for (j = 0; j < 10; j++)
+	;
+      #pragma omp single		/* { dg-error "region may not be closely nested inside of" } */
+      ;
+      #pragma omp sections		/* { dg-error "region may not be closely nested inside of" } */
+      {
+	#pragma omp section
+	;
+      }
+      #pragma omp barrier		/* { dg-error "region may not be closely nested inside of" } */
+      #pragma omp master		/* { dg-error "region may not be closely nested inside of" } */
+      ;
+      #pragma omp ordered		/* { dg-error "region may not be closely nested inside of" } */
+      ;
+      #pragma omp ordered threads	/* { dg-error "region may not be closely nested inside of" } */
+      ;
+      #pragma omp ordered simd threads	/* { dg-error ".ordered. .simd. must be closely nested inside .simd. region" } */
+      ;
+      #pragma omp simd
+      for (j = 0; j < 10; j++)
+	#pragma omp ordered simd
+	  ;
+      #pragma omp critical
+      {
+	#pragma omp simd
+	for (j = 0; j < 10; j++)
+	  #pragma omp ordered simd
+	    ;
+      }
+    }
+  #pragma omp taskloop
+  for (i = 0; i < 64; i++)
+    #pragma omp parallel
+    {
+      int j;
+      #pragma omp for
+      for (j = 0; j < 10; j++)
+	;
+      #pragma omp single
+      ;
+      #pragma omp sections
+      {
+	#pragma omp section
+	;
+      }
+      #pragma omp barrier
+      #pragma omp master
+      ;
+      #pragma omp ordered		/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
+      ;
+      #pragma omp ordered threads	/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
+      ;
+      #pragma omp simd
+      for (j = 0; j < 10; j++)
+	#pragma omp ordered simd
+	  ;
+      #pragma omp critical
+      {
+	#pragma omp simd
+	for (j = 0; j < 10; j++)
+	  #pragma omp ordered simd
+	    ;
+      }
+    }
+  #pragma omp taskloop
+  for (i = 0; i < 64; i++)
+    #pragma omp target
+    {
+      int j;
+      #pragma omp for
+      for (j = 0; j < 10; j++)
+	;
+      #pragma omp single
+      ;
+      #pragma omp sections
+      {
+	#pragma omp section
+	;
+      }
+      #pragma omp barrier
+      #pragma omp master
+      ;
+      #pragma omp ordered		/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
+      ;
+      #pragma omp ordered threads	/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
+      ;
+      #pragma omp simd
+      for (j = 0; j < 10; j++)
+	#pragma omp ordered simd
+	  ;
+      #pragma omp critical
+      {
+	#pragma omp simd
+	for (j = 0; j < 10; j++)
+	  #pragma omp ordered simd
+	    ;
+      }
+    }
+  #pragma omp ordered
+  {
+    #pragma omp ordered			/* { dg-error "region may not be closely nested inside of" } */
+    ;
+  }
+  #pragma omp ordered threads
+  {
+    #pragma omp ordered			/* { dg-error "region may not be closely nested inside of" } */
+    ;
+  }
+  #pragma omp ordered
+  {
+    #pragma omp ordered threads		/* { dg-error "region may not be closely nested inside of" } */
+    ;
+  }
+  #pragma omp ordered threads
+  {
+    #pragma omp ordered threads		/* { dg-error "region may not be closely nested inside of" } */
+    ;
+  }
+  #pragma omp critical
+  {
+    #pragma omp ordered simd		/* { dg-error ".ordered. .simd. must be closely nested inside .simd. region" } */
+    ;
+  }
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    #pragma omp parallel
+    {
+      #pragma omp ordered threads	/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
+      ;
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    #pragma omp parallel
+    {
+      #pragma omp ordered		/* { dg-error ".ordered. region must be closely nested inside a loop region with an .ordered. clause" } */
+      ;
+    }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 64; i++)
+    #pragma omp parallel
+    {
+      #pragma omp ordered depend(source)	/* { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered depend(sink: i - 1)	/* { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+    }
+}
--- gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c.jj	2015-10-14 10:25:30.000000000 +0200
+++ gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c	2015-11-06 17:33:30.112372850 +0100
@@ -5,19 +5,19 @@  f_omp_target (void)
 {
 #pragma omp target
   {
-#pragma omp target /* { dg-warning "target construct inside of target region" } */
+#pragma omp target /* { dg-warning ".target. construct inside of .target. region" } */
     ;
-#pragma omp target data map(i) /* { dg-warning "target data construct inside of target region" } */
+#pragma omp target data map(i) /* { dg-warning ".target data. construct inside of .target. region" } */
     ;
-#pragma omp target update to(i) /* { dg-warning "target update construct inside of target region" } */
+#pragma omp target update to(i) /* { dg-warning ".target update. construct inside of .target. region" } */
 
 #pragma omp parallel
     {
-#pragma omp target /* { dg-warning "target construct inside of target region" } */
+#pragma omp target /* { dg-warning ".target. construct inside of .target. region" } */
       ;
-#pragma omp target data map(i) /* { dg-warning "target data construct inside of target region" } */
+#pragma omp target data map(i) /* { dg-warning ".target data. construct inside of .target. region" } */
       ;
-#pragma omp target update to(i) /* { dg-warning "target update construct inside of target region" } */
+#pragma omp target update to(i) /* { dg-warning ".target update. construct inside of .target. region" } */
     }
   }
 }
--- gcc/testsuite/c-c++-common/gomp/ordered-3.c.jj	2015-10-14 10:25:30.000000000 +0200
+++ gcc/testsuite/c-c++-common/gomp/ordered-3.c	2015-11-06 18:33:07.852934306 +0100
@@ -59,6 +59,18 @@  foo (void)
       #pragma omp ordered depend(sink: i - 1)	/* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
       #pragma omp ordered depend(source)	/* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
     }
+  #pragma omp parallel for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend(sink: i - 1)	/* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered depend(source)	/* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+    }
+  #pragma omp parallel for
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend(sink: i - 1)	/* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered depend(source)	/* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+    }
 }
 
 void
--- gcc/testsuite/c-c++-common/gomp/ordered-4.c.jj	2015-11-06 18:38:49.998126943 +0100
+++ gcc/testsuite/c-c++-common/gomp/ordered-4.c	2015-11-06 18:42:22.845142557 +0100
@@ -0,0 +1,54 @@ 
+void
+f1 (void)
+{
+  int i, j;
+  #pragma omp critical
+  {
+    #pragma omp simd
+    for (i = 0; i < 64; i++)
+      {
+	#pragma omp ordered simd
+	;
+      }
+  }
+  #pragma omp ordered threads
+  {
+    #pragma omp simd
+    for (i = 0; i < 64; i++)
+      {
+	#pragma omp ordered simd
+	;
+      }
+  }
+  #pragma omp task
+  {
+    #pragma omp simd
+    for (i = 0; i < 64; i++)
+      {
+	#pragma omp ordered simd
+	;
+      }
+  }
+  #pragma omp taskloop
+  for (j = 0; j < 64; j++)
+    #pragma omp simd
+    for (i = 0; i < 64; i++)
+      {
+	#pragma omp ordered simd
+	;
+      }
+}
+
+void
+f2 (void)
+{
+  #pragma omp ordered simd
+  ;
+}
+
+void
+f3 (void)
+{
+  #pragma omp ordered threads , simd
+  ;
+}