]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Diagnose another case of mixing parameter and attribute syntax
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Aug 2021 07:18:23 +0000 (09:18 +0200)
committerJakub Jelinek <jakub@redhat.com>
Thu, 12 Aug 2021 07:34:16 +0000 (09:34 +0200)
This patch diagnoses cases like:
  #pragma omp parallel
  [[omp::directive (declare simd)]] int foo ();
or
  #pragma omp taskgroup
  int bar [[omp::directive (declare simd)]] (int);
where the pragma is on the same declaration statement as the declare simd
attribute.

2021-08-12  Jakub Jelinek  <jakub@redhat.com>

* parser.c (cp_parser_lambda_body): Add temp overrides
for parser->{omp_declare_simd,oacc_routine,omp_attrs_forbidden_p}.
(cp_parser_statement): Restore parser->omp_attrs_forbidden_p for
cp_parser_declaration_statement.
(cp_parser_default_argument): Add temp override for
parser->omp_attrs_forbidden_p.
(cp_parser_late_parsing_omp_declare_simd): Diagnose declare simd
or declare variant in attribute syntax on a declaration immediately
following an OpenMP construct in pragma syntax.

* g++.dg/gomp/attrs-11.C: Add new tests.

gcc/cp/parser.c
gcc/testsuite/g++.dg/gomp/attrs-11.C

index ec885d774f2f80cbd681056951e407cd5d667bcc..fbb81306c7b5b4d0e9c3a2828e9fda71613a03ca 100644 (file)
@@ -11628,6 +11628,9 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
        middle of an expression.  */
     ++function_depth;
 
+  auto odsd = make_temp_override (parser->omp_declare_simd, NULL);
+  auto ord = make_temp_override (parser->oacc_routine, NULL);
+  auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false);
   vec<tree> omp_privatization_save;
   save_omp_privatization_clauses (omp_privatization_save);
   /* Clear this in case we're in the middle of a default argument.  */
@@ -12271,9 +12274,11 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
               so let's un-parse them.  */
            saved_tokens.rollback();
 
+         parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p;
          cp_parser_parse_tentatively (parser);
          /* Try to parse the declaration-statement.  */
          cp_parser_declaration_statement (parser);
+         parser->omp_attrs_forbidden_p = false;
          /* If that worked, we're done.  */
          if (cp_parser_parse_definitely (parser))
            return;
@@ -24768,6 +24773,8 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
   parser->greater_than_is_operator_p = !template_parm_p;
   auto odsd = make_temp_override (parser->omp_declare_simd, NULL);
   auto ord = make_temp_override (parser->oacc_routine, NULL);
+  auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false);
+
   /* Local variable names (and the `this' keyword) may not
      appear in a default argument.  */
   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
@@ -44503,6 +44510,14 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
                    continue;
                  }
 
+               if (parser->omp_attrs_forbidden_p)
+                 {
+                   error_at (first->location,
+                             "mixing OpenMP directives with attribute and "
+                             "pragma syntax on the same statement");
+                   parser->omp_attrs_forbidden_p = false;
+                 }
+
                if (!flag_openmp && strcmp (directive[1], "simd") != 0)
                  continue;
                if (lexer == NULL)
index 009bcb2d87f69829da73a795b7d90e6d9614dacf..44e025e7540456a859fa4c1881259d6f4a19acf2 100644 (file)
@@ -72,3 +72,15 @@ int f28 [[omp::directive (declare simd), omp::directive (foobar)]] (int);    // { d
 int f29 [[omp::directive (foobar), omp::directive (declare simd)]] (int);      // { dg-error "unknown OpenMP directive name" }
 int f30 [[omp::directive (threadprivate (t7)), omp::directive (declare simd)]] (int);  // { dg-error "OpenMP directive other than 'declare simd' or 'declare variant' appertains to a declaration" }
 int f31 [[omp::directive (declare simd), omp::directive (threadprivate (t8))]] (int);  // { dg-error "OpenMP directive other than 'declare simd' or 'declare variant' appertains to a declaration" }
+
+void
+baz ()
+{
+  #pragma omp parallel
+  [[omp::directive (declare simd)]] extern int f32 (int);      // { dg-error "mixing OpenMP directives with attribute and pragma syntax on the same statement" }
+  #pragma omp parallel
+  extern int f33 [[omp::directive (declare simd)]] (int);      // { dg-error "mixing OpenMP directives with attribute and pragma syntax on the same statement" }
+  [[omp::directive (parallel)]]
+  #pragma omp declare simd     // { dg-error "mixing OpenMP directives with attribute and pragma syntax on the same statement" }
+  extern int f34 (int);
+}