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