]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Diagnose syntax mismatches between declare target and end declare target
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Aug 2021 09:25:26 +0000 (11:25 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Thu, 12 Aug 2021 09:25:26 +0000 (11:25 +0200)
OpenMP 5.1 says:
For any directive that has a paired end directive, including those with a begin
and end pair, both directives must use either the attribute syntax or the
pragma syntax.

The following patch enforces it with the only pair so far recognized in C++
(Fortran has many, but on the other side doesn't have attribute syntax).

While I initially wanted to use vec<bool, va_gc> *member; in there, that
unfortunately doesn't work, one gets linker errors and I guess it is fixable,
but for begin declare target we'll need a struct anyway to store device_type
etc.

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

* cp-tree.h (omp_declare_target_attr): New type.
(struct saved_scope): Change type of omp_declare_target_attribute
from int to vec<omp_declare_target_attr, va_gc> * and move it.
* parser.c (cp_parser_omp_declare_target): Instead of
incrementing scope_chain->omp_declare_target_attribute, push
a struct containing parser->lexer->in_omp_attribute_pragma to
the vector.
(cp_parser_omp_end_declare_target): Instead of decrementing
scope_chain->omp_declare_target_attribute, pop a structure
from it.  Diagnose mismatching declare target vs.
end declare target syntax.
* semantics.c (finish_translation_unit): Use vec_safe_length
and vec_safe_truncate on scope_chain->omp_declare_target_attributes.
* decl2.c (cplus_decl_attributes): Use vec_safe_length
on scope_chain->omp_declare_target_attributes.

* g++.dg/gomp/attrs-12.C: New test.

(cherry picked from commit 01f8a8b48e50cbaa68b878d9f8a330b8c0736bed)

gcc/cp/ChangeLog.omp
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog.omp
gcc/testsuite/g++.dg/gomp/attrs-12.C [new file with mode: 0644]

index 1daae13533a905e90bd65d2c823a760903de1b5f..b2a41e15f9da6dfc75175793273830fdde0bd50d 100644 (file)
@@ -1,3 +1,24 @@
+2021-08-12  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * cp-tree.h (omp_declare_target_attr): New type.
+       (struct saved_scope): Change type of omp_declare_target_attribute
+       from int to vec<omp_declare_target_attr, va_gc> * and move it.
+       * parser.c (cp_parser_omp_declare_target): Instead of
+       incrementing scope_chain->omp_declare_target_attribute, push
+       a struct containing parser->lexer->in_omp_attribute_pragma to
+       the vector.
+       (cp_parser_omp_end_declare_target): Instead of decrementing
+       scope_chain->omp_declare_target_attribute, pop a structure
+       from it.  Diagnose mismatching declare target vs.
+       end declare target syntax.
+       * semantics.c (finish_translation_unit): Use vec_safe_length
+       and vec_safe_truncate on scope_chain->omp_declare_target_attributes.
+       * decl2.c (cplus_decl_attributes): Use vec_safe_length
+       on scope_chain->omp_declare_target_attributes.
+
 2021-08-12  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index 792ee9324716ad8722b89b6389f04bc45c66b1f7..c1b49fa770704c5b926226a2cbd287af88deab91 100644 (file)
@@ -1764,6 +1764,10 @@ union GTY((desc ("cp_tree_node_structure (&%h)"),
 };
 
 \f
+struct GTY(()) omp_declare_target_attr {
+  bool attr_syntax;
+};
+
 /* Global state.  */
 
 struct GTY(()) saved_scope {
@@ -1798,9 +1802,6 @@ struct GTY(()) saved_scope {
   int unevaluated_operand;
   int inhibit_evaluation_warnings;
   int noexcept_operand;
-  /* If non-zero, implicit "omp declare target" attribute is added into the
-     attribute lists.  */
-  int omp_declare_target_attribute;
   int ref_temp_count;
 
   struct stmt_tree_s x_stmt_tree;
@@ -1809,6 +1810,7 @@ struct GTY(()) saved_scope {
   cp_binding_level *bindings;
 
   hash_map<tree, tree> *GTY((skip)) x_local_specializations;
+  vec<omp_declare_target_attr, va_gc> *omp_declare_target_attribute;
 
   struct saved_scope *prev;
 };
index f32c0f830b0fcce3b7161bd675210eacd81c8d1d..cf433acde652644d12d5cf6254fcd9af5c7e1e49 100644 (file)
@@ -1550,7 +1550,7 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
     return;
 
   /* Add implicit "omp declare target" attribute if requested.  */
-  if (scope_chain->omp_declare_target_attribute
+  if (vec_safe_length (scope_chain->omp_declare_target_attribute)
       && ((VAR_P (*decl)
           && (TREE_STATIC (*decl) || DECL_EXTERNAL (*decl)))
          || TREE_CODE (*decl) == FUNCTION_DECL))
index 88415805aa39145c5e54739de731d1f974f85570..aeaa4f5bd0652d62bd204b6d3862f2d0d8b05421 100644 (file)
@@ -44432,8 +44432,10 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
     }
   else
     {
+      struct omp_declare_target_attr a
+       = { parser->lexer->in_omp_attribute_pragma };
+      vec_safe_push (scope_chain->omp_declare_target_attribute, a);
       cp_parser_require_pragma_eol (parser, pragma_tok);
-      scope_chain->omp_declare_target_attribute++;
       return;
     }
   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
@@ -44514,6 +44516,7 @@ static void
 cp_parser_omp_end_declare_target (cp_parser *parser, cp_token *pragma_tok)
 {
   const char *p = "";
+  bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -44544,12 +44547,26 @@ cp_parser_omp_end_declare_target (cp_parser *parser, cp_token *pragma_tok)
       return;
     }
   cp_parser_require_pragma_eol (parser, pragma_tok);
-  if (!scope_chain->omp_declare_target_attribute)
+  if (!vec_safe_length (scope_chain->omp_declare_target_attribute))
     error_at (pragma_tok->location,
              "%<#pragma omp end declare target%> without corresponding "
              "%<#pragma omp declare target%>");
   else
-    scope_chain->omp_declare_target_attribute--;
+    {
+      omp_declare_target_attr
+       a = scope_chain->omp_declare_target_attribute->pop ();
+      if (a.attr_syntax != in_omp_attribute_pragma)
+       {
+         if (a.attr_syntax)
+           error_at (pragma_tok->location,
+                     "%<declare target%> in attribute syntax terminated "
+                     "with %<end declare target%> in pragma syntax");
+         else
+           error_at (pragma_tok->location,
+                     "%<declare target%> in pragma syntax terminated "
+                     "with %<end declare target%> in attribute syntax");
+       }
+    }
 }
 
 /* Helper function of cp_parser_omp_declare_reduction.  Parse the combiner
index ec4ec509b18c49321eb33b250eea87726cc56cb3..e412338922e96c29b6673c6f72ca4e1f9bff4b8a 100644 (file)
@@ -3213,12 +3213,12 @@ finish_translation_unit (void)
   /* Do file scope __FUNCTION__ et al.  */
   finish_fname_decls ();
 
-  if (scope_chain->omp_declare_target_attribute)
+  if (vec_safe_length (scope_chain->omp_declare_target_attribute))
     {
       if (!errorcount)
        error ("%<#pragma omp declare target%> without corresponding "
               "%<#pragma omp end declare target%>");
-      scope_chain->omp_declare_target_attribute = 0;
+      vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0);
     }
 }
 
index a8f0c77b003009fcc875dbd695680ce5fc3287da..802ca90127de4c62011e2b98f86ae5adf09de7a2 100644 (file)
@@ -1,3 +1,10 @@
+2021-08-12  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/gomp/attrs-12.C: New test.
+
 2021-08-12  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-12.C b/gcc/testsuite/g++.dg/gomp/attrs-12.C
new file mode 100644 (file)
index 0000000..b613872
--- /dev/null
@@ -0,0 +1,41 @@
+// { dg-do compile { target c++11 } }
+
+#pragma omp declare target
+#pragma omp declare target
+[[omp::directive (declare target)]];
+int a;
+[[omp::directive (end declare target)]];
+#pragma omp end declare target
+#pragma omp end declare target
+[[omp::directive (declare target)]];
+int b;
+#pragma omp end declare target         // { dg-error "'declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" }
+#pragma omp declare target
+int c;
+[[omp::directive (end declare target)]];// { dg-error "'declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" }
+#pragma omp declare target
+[[omp::directive (declare target)]];
+int d;
+#pragma omp end declare target         // { dg-error "'declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" }
+#pragma omp declare target
+int e;
+[[omp::directive (end declare target)]];// { dg-error "'declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" }
+#pragma omp end declare target
+[[omp::directive (declare target)]];
+[[omp::directive (declare target)]];
+int f;
+#pragma omp end declare target         // { dg-error "'declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" }
+#pragma omp declare target
+int g;
+[[omp::directive (end declare target)]];// { dg-error "'declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" }
+[[omp::directive (end declare target)]];
+[[omp::directive (declare target)]];
+#pragma omp declare target
+int h;
+#pragma omp end declare target
+#pragma omp end declare target         // { dg-error "'declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" }
+#pragma omp declare target
+[[omp::directive (declare target)]];
+int i;
+[[omp::directive (end declare target)]];
+[[omp::directive (end declare target)]];// { dg-error "'declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" }