Hi!

For ordered depend we unfortunately need to diagnose incorrect length or
contents of the sink vec before OpenMP region nesting is diagnosed,
so this patch diagnoses the incorrect nesting before the diagnostics,
to avoid confusing errors.  Also the patch allows ordered clause
on for simd, but only if ordered has no parameter.  To be used with
#pragma omp ordered threads simd construct.

2015-10-13  Jakub Jelinek  <ja...@redhat.com>

        * gimplify.c (gimplify_omp_ordered): Diagnose ordered depend
        inside loop without ordered(n) clause.
        * omp-low.c (check_omp_nesting_restrictions): Use a different
        wording if ordered clause is present, but without parameter.
c/
        * c-parser.c (c_parser_omp_simd): Allow ordered clause on
        for simd, but ensure no parameter is specified for it.
cp/
        * parser.c (cp_parser_omp_simd): Allow ordered clause on
        for simd, but ensure no parameter is specified for it.
testsuite/
        * c-c++-common/gomp/ordered-3.c: New test.

--- gcc/gimplify.c.jj   2015-10-12 12:37:32.000000000 +0200
+++ gcc/gimplify.c      2015-10-12 13:43:30.732469344 +0200
@@ -8749,7 +8749,18 @@ gimplify_omp_ordered (tree expr, gimple_
   if (gimplify_omp_ctxp)
     for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-         && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+         && gimplify_omp_ctxp->loop_iter_var.is_empty ()
+         && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
+             || 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");
+         failures++;
+       }
+      else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
+              && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
        {
          bool fail = false;
          for (decls = OMP_CLAUSE_DECL (c), i = 0;
--- gcc/omp-low.c.jj    2015-10-12 12:21:32.000000000 +0200
+++ gcc/omp-low.c       2015-10-12 13:40:39.750083213 +0200
@@ -3375,14 +3375,21 @@ check_omp_nesting_restrictions (gimple s
                  || gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
                  || (oclause
                        = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
-                                          OMP_CLAUSE_ORDERED)) == NULL_TREE
-                 || OMP_CLAUSE_ORDERED_EXPR (oclause) == NULL_TREE)
+                                          OMP_CLAUSE_ORDERED)) == NULL_TREE)
                {
                  error_at (OMP_CLAUSE_LOCATION (c),
                            "%<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");
+                 return false;
+               }
            }
          else
            {
--- gcc/c/c-parser.c.jj 2015-10-09 09:26:12.000000000 +0200
+++ gcc/c/c-parser.c    2015-10-12 13:26:52.275752160 +0200
@@ -14009,13 +14009,21 @@ c_parser_omp_simd (location_t loc, c_par
 
   strcat (p_name, " simd");
   mask |= OMP_SIMD_CLAUSE_MASK;
-  mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
 
   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   if (cclauses)
     {
       omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
+      tree c = find_omp_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
+                               OMP_CLAUSE_ORDERED);
+      if (c && OMP_CLAUSE_ORDERED_EXPR (c))
+       {
+         error_at (OMP_CLAUSE_LOCATION (c),
+                   "%<ordered%> clause with parameter may not be specified "
+                   "on %qs construct", p_name);
+         OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
+       }
     }
 
   block = c_begin_compound_stmt (true);
--- gcc/cp/parser.c.jj  2015-10-09 09:27:22.000000000 +0200
+++ gcc/cp/parser.c     2015-10-12 13:27:43.600966307 +0200
@@ -32527,7 +32527,6 @@ cp_parser_omp_simd (cp_parser *parser, c
 
   strcat (p_name, " simd");
   mask |= OMP_SIMD_CLAUSE_MASK;
-  mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
 
   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
                                       cclauses == NULL);
@@ -32535,6 +32534,15 @@ cp_parser_omp_simd (cp_parser *parser, c
     {
       cp_omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
+      tree c = find_omp_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
+                               OMP_CLAUSE_ORDERED);
+      if (c && OMP_CLAUSE_ORDERED_EXPR (c))
+       {
+         error_at (OMP_CLAUSE_LOCATION (c),
+                   "%<ordered%> clause with parameter may not be specified "
+                   "on %qs construct", p_name);
+         OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
+       }
     }
 
   sb = begin_omp_structured_block ();
--- gcc/testsuite/c-c++-common/gomp/ordered-3.c.jj      2015-10-12 
12:49:11.166229129 +0200
+++ gcc/testsuite/c-c++-common/gomp/ordered-3.c 2015-10-12 13:44:50.349252214 
+0200
@@ -0,0 +1,91 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+void
+foo (void)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered
+      ;
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered threads
+      ;
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered threads threads      /* { dg-error "too many 
.threads. clauses" } */
+      ;
+    }
+  #pragma omp simd
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered simd
+      ;
+    }
+  #pragma omp simd
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered simd simd            /* { dg-error "too many .simd. 
clauses" } */
+      ;
+    }
+  #pragma omp for simd ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered threads, simd
+      ;
+    }
+  #pragma omp for simd ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered threads, simd, threads, simd /* { dg-error "too many 
.threads. clauses" } */
+      ;        /* { dg-error "too many .simd. clauses" "" { target *-*-* } 47 
} */
+    }
+  #pragma omp for simd ordered(1)      /* { dg-error ".ordered. clause with 
parameter may not be specified on .#pragma omp for simd. construct" } */
+  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 simd ordered(1)     /* { dg-error ".ordered. clause 
with parameter may not be specified on .#pragma omp parallel for simd. 
construct" } */
+  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
+bar (int x)
+{
+  switch (x)
+    {
+    case 0:
+      #pragma omp ordered
+      ;
+      break;
+    case 1:
+      #pragma omp ordered threads
+      ;
+      break;
+    case 2:
+      #pragma omp ordered threads, threads     /* { dg-error "too many 
.threads. clauses" } */
+      ;
+      break;
+    }
+}
+
+void
+baz (void)
+{
+  #pragma omp ordered simd
+  ;
+  #pragma omp ordered simd, simd               /* { dg-error "too many .simd. 
clauses" } */
+  ;
+}

        Jakub

Reply via email to