]> 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 07:26:27 +0000 (09:26 +0200)
committerJakub Jelinek <jakub@redhat.com>
Thu, 12 Aug 2021 07:34:16 +0000 (09:34 +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.

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

index 6a8264b0c618a43fe7d74ad62ca2cea3d0c0b2cd..bd3f12a393e4d1507b2400586c91ce19a6687e77 100644 (file)
@@ -1789,6 +1789,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 {
@@ -1826,9 +1830,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;
@@ -1837,6 +1838,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 ba27388df5dcc8bfb9b37a746b4229b60df7d78b..0c9d2f468a02f2a487f3811f86e98c21e28ecc38 100644 (file)
@@ -1551,7 +1551,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 fbb81306c7b5b4d0e9c3a2828e9fda71613a03ca..74de52992bca9c5f6bd8c63515dd7192c6f117c6 100644 (file)
@@ -44641,8 +44641,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))
@@ -44723,6 +44725,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;
@@ -44753,12 +44756,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 34e5d7610b05910912583f7aad6dd7fe19ea0f73..2e23818cdd98752f2a17541425c7a30bd17c9db5 100644 (file)
@@ -3271,12 +3271,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);
     }
 }
 
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" }