Hi!

Commas in between OpenMP clauses are normally allowed, but not required
in OpenMP directives, but construct={simd(...)} properties are special
because the grammar requires there that the individual trait-properties
are comma separated.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk.

2019-10-14  Jakub Jelinek  <ja...@redhat.com>

c/
        * c-parser.c (c_parser_omp_all_clauses): Change bool NESTED_P argument
        into int NESTED, if it is 2, diagnose missing commas in between
        clauses.
        (c_parser_omp_context_selector): Pass 2 as last argument to
        c_parser_omp_all_clauses.
cp/
        * parser.c (cp_parser_omp_all_clauses): Change bool NESTED_P argument
        into int NESTED, if it is 2, diagnose missing commas in between
        clauses.
        (cp_parser_omp_context_selector): Pass 2 as last argument to
        cp_parser_omp_all_clauses.
testsuite/
        * c-c++-common/gomp/declare-variant-7.c: Add tests for clauses not
        separated by commas in simd selector trait properties.

--- gcc/c/c-parser.c.jj 2019-10-12 10:26:18.125940185 +0200
+++ gcc/c/c-parser.c    2019-10-13 12:23:26.194593730 +0200
@@ -15215,13 +15215,14 @@ c_parser_oacc_all_clauses (c_parser *par
 /* Parse all OpenMP clauses.  The set clauses allowed by the directive
    is a bitmask in MASK.  Return the list of clauses found.
    FINISH_P set if c_finish_omp_clauses should be called.
-   NESTED_P set if clauses should be terminated by closing paren instead
-   of end of pragma.  */
+   NESTED non-zero if clauses should be terminated by closing paren instead
+   of end of pragma.  If it is 2, additionally commas are required in between
+   the clauses.  */
 
 static tree
 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
                          const char *where, bool finish_p = true,
-                         bool nested_p = false)
+                         int nested = 0)
 {
   tree clauses = NULL;
   bool first = true;
@@ -15233,11 +15234,18 @@ c_parser_omp_all_clauses (c_parser *pars
       const char *c_name;
       tree prev = clauses;
 
-      if (nested_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+      if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
        break;
 
-      if (!first && c_parser_next_token_is (parser, CPP_COMMA))
-       c_parser_consume_token (parser);
+      if (!first)
+       {
+         if (c_parser_next_token_is (parser, CPP_COMMA))
+           c_parser_consume_token (parser);
+         else if (nested == 2)
+           error_at (c_parser_peek_token (parser)->location,
+                     "clauses in %<simd%> trait should be separated "
+                     "by %<,%>");
+       }
 
       here = c_parser_peek_token (parser)->location;
       c_kind = c_parser_omp_clause_name (parser);
@@ -15520,7 +15528,7 @@ c_parser_omp_all_clauses (c_parser *pars
     }
 
  saw_error:
-  if (!nested_p)
+  if (!nested)
     c_parser_skip_to_pragma_eol (parser);
 
   if (finish_p)
@@ -19279,7 +19287,7 @@ c_parser_omp_context_selector (c_parser
              tree c;
              c = c_parser_omp_all_clauses (parser,
                                            OMP_DECLARE_SIMD_CLAUSE_MASK,
-                                           "simd", true, true);
+                                           "simd", true, 2);
              c = c_omp_declare_simd_clauses_to_numbers (parms
                                                         == error_mark_node
                                                         ? NULL_TREE : parms,
--- gcc/cp/parser.c.jj  2019-10-12 10:26:18.133940064 +0200
+++ gcc/cp/parser.c     2019-10-13 12:24:15.929846078 +0200
@@ -36078,13 +36078,14 @@ cp_parser_oacc_all_clauses (cp_parser *p
 /* Parse all OpenMP clauses.  The set clauses allowed by the directive
    is a bitmask in MASK.  Return the list of clauses found.
    FINISH_P set if finish_omp_clauses should be called.
-   NESTED_P set if clauses should be terminated by closing paren instead
-   of end of pragma.  */
+   NESTED non-zero if clauses should be terminated by closing paren instead
+   of end of pragma.  If it is 2, additionally commas are required in between
+   the clauses.  */
 
 static tree
 cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
                           const char *where, cp_token *pragma_tok,
-                          bool finish_p = true, bool nested_p = false)
+                          bool finish_p = true, int nested = 0)
 {
   tree clauses = NULL;
   bool first = true;
@@ -36099,11 +36100,18 @@ cp_parser_omp_all_clauses (cp_parser *pa
       const char *c_name;
       tree prev = clauses;
 
-      if (nested_p && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+      if (nested && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
        break;
 
-      if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
-       cp_lexer_consume_token (parser->lexer);
+      if (!first)
+       {
+         if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+           cp_lexer_consume_token (parser->lexer);
+         else if (nested == 2)
+           error_at (cp_lexer_peek_token (parser->lexer)->location,
+                     "clauses in %<simd%> trait should be separated "
+                      "by %<,%>");
+       }
 
       token = cp_lexer_peek_token (parser->lexer);
       c_kind = cp_parser_omp_clause_name (parser);
@@ -36421,7 +36429,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
        }
     }
  saw_error:
-  if (!nested_p)
+  if (!nested)
     cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   if (finish_p)
     {
@@ -40548,7 +40556,7 @@ cp_parser_omp_context_selector (cp_parse
              properties
                = cp_parser_omp_all_clauses (parser,
                                             OMP_DECLARE_SIMD_CLAUSE_MASK,
-                                            "simd", NULL, true, true);
+                                            "simd", NULL, true, 2);
              break;
            default:
              gcc_unreachable ();
--- gcc/testsuite/c-c++-common/gomp/declare-variant-7.c.jj      2019-10-12 
10:26:18.134940050 +0200
+++ gcc/testsuite/c-c++-common/gomp/declare-variant-7.c 2019-10-13 
12:29:55.533727289 +0200
@@ -27,7 +27,11 @@ int f10 (float x, float y, float *q);
 int f11 (float x, float y, float *z);
 #pragma omp declare variant (f3) match 
(construct={simd(simdlen(4),inbranch,linear(y:1))})
 int f12 (int x, int y);
-#pragma omp declare variant (f3) match 
(construct={simd(inbranch,simdlen(5-1),linear(q:4-3))})
+#pragma omp declare variant (f3) match (construct={simd(inbranch, simdlen 
(5-1), linear (q:4-3))})
 int f13 (int x, int q);
 #pragma omp declare variant (f3) match 
(construct={simd(inbranch,simdlen(4),linear(q:2))})             /* { dg-error 
"'f3' used as a variant with incompatible 'constructor' selector sets" "" { 
target c } } */
 int f14 (int x, int q);
+#pragma omp declare variant (f3) match (construct={simd(inbranch simdlen (4) 
linear (q:1))})           /* { dg-error "clauses in 'simd' trait should be 
separated by ','" } */
+int f15 (int x, int q);
+#pragma omp declare variant (f3) match (construct={simd(inbranch, simdlen 
(5-1) linear (q:4-3))})      /* { dg-error "clauses in 'simd' trait should be 
separated by ','" } */
+int f16 (int x, int q);

        Jakub

Reply via email to