At least one of the diagnostics in cp_parser_omp_allocate expects each decl
to have been pushed into the current binding level. Due to when attributes
are parsed this assumption does not hold for an allocate directive
specified in an omp::decl attribute. The broken diagnostic checks that the
vars listed in an allocate directive are in the same scope as the directive.
Obviously we can assume that is the case when using omp::decl, but it is not
obvious how to detect that we in an omp::decl in a robust way so this case
is simply not supported for now.
This patch also adds a check for TREE_PUBLIC in cp_maybe_parse_omp_decl.
During investigation of this issue it was noticed that TREE_PUBLIC denotes
an omp::decl attribute as opposed to an omp::directive attribute, thus it is
also a precondition in that function.
gcc/cp/ChangeLog:
* parser.cc (cp_maybe_parse_omp_decl): Sorry for allocate directive.
libgomp/ChangeLog:
* testsuite/libgomp.c-c++-common/allocate-7.c: Disable for C++.
gcc/testsuite/ChangeLog:
* g++.dg/gomp/omp-constexpr.C: Add sorry for allocate directive.
* g++.dg/gomp/allocate-24.C: New test.
Signed-off-by: Waffl3x <[email protected]>
---
gcc/cp/parser.cc | 10 ++++++-
gcc/testsuite/g++.dg/gomp/allocate-24.C | 26 +++++++++++++++++++
gcc/testsuite/g++.dg/gomp/omp-constexpr.C | 3 ++-
.../libgomp.c-c++-common/allocate-7.c | 5 +++-
4 files changed, 41 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/gomp/allocate-24.C
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 791ac2d6ea9..fe628be065c 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -54410,7 +54410,8 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser
*parser, tree attrs,
bool
cp_maybe_parse_omp_decl (tree decl, tree d)
{
- gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
+ gcc_assert (TREE_CODE (d) == DEFERRED_PARSE
+ && TREE_PUBLIC (d));
cp_token *first = DEFPARSE_TOKENS (d)->first;
cp_token *last = DEFPARSE_TOKENS (d)->last;
const char *directive[3] = {};
@@ -54448,6 +54449,13 @@ cp_maybe_parse_omp_decl (tree decl, tree d)
if (!flag_openmp && !dir->simd)
return true;
+ if (dir->id == PRAGMA_OMP_ALLOCATE)
+ {
+ sorry_at (first->location,
+ "allocate directive not supported in %<omp::decl%>");
+ return true;
+ }
+
cp_parser *parser = the_parser;
cp_lexer *lexer = cp_lexer_alloc ();
lexer->debugging_p = parser->lexer->debugging_p;
diff --git a/gcc/testsuite/g++.dg/gomp/allocate-24.C
b/gcc/testsuite/g++.dg/gomp/allocate-24.C
new file mode 100644
index 00000000000..114231c8a54
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/allocate-24.C
@@ -0,0 +1,26 @@
+/* { dg-do compile { target c++11 } } */
+
+#include "allocate-allocator-handle.h"
+
+/* TODO: Add scan-tree-dump checks once support for omp::decl is added. */
+
+int AAA [[omp::decl(allocate,allocator(omp_low_lat_mem_alloc),align(4096))]];
+/* { dg-message "allocate directive not supported in 'omp::decl'" "" { target
*-*-* } .-1 } */
+
+static_assert (alignof(AAA) == alignof(int), "wrong alignment");
+
+void f ()
+{
+ /* This applies to A1 and B1.
+ (C++23 N4950 ยง9.1.3, sentence 5)
+ The attribute-specifier-seq appertains to each of the entities declared by
+ the declarators of the init-declarator-list. */
+ [[omp::decl(allocate, align(4096))]] int A1[5], B1;
+ /* { dg-message "allocate directive not supported in 'omp::decl'" "" {
target *-*-* } .-1 } */
+
+ static_assert (alignof(A1) == alignof(int[5]), "wrong alignment");
+ static_assert (alignof(B1) == alignof(int), "wrong alignment");
+
+ static int BBB
[[omp::decl(allocate,allocator(omp_low_lat_mem_alloc),align(4096))]];
+ /* { dg-message "allocate directive not supported in 'omp::decl'" "" {
target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/g++.dg/gomp/omp-constexpr.C
b/gcc/testsuite/g++.dg/gomp/omp-constexpr.C
index 0d984d8609b..85b1157201c 100644
--- a/gcc/testsuite/g++.dg/gomp/omp-constexpr.C
+++ b/gcc/testsuite/g++.dg/gomp/omp-constexpr.C
@@ -31,7 +31,8 @@ h ()
constexpr int
i ()
{
- int a [[omp::decl(allocate, align(128))]] = 42; /* { dg-error "OpenMP
directives may not appear in 'constexpr' functions" } */
+ int a [[omp::decl(allocate, align(128))]] = 42; /* { dg-error "OpenMP
directives may not appear in 'constexpr' functions" "" { xfail *-*-* } } */
+ /* { dg-message "allocate directive not supported in 'omp::decl'" "" {
target *-*-* } .-1 } */
return a;
} // { dg-error "not a return-statement" "" { target c++11_down } }
diff --git a/libgomp/testsuite/libgomp.c-c++-common/allocate-7.c
b/libgomp/testsuite/libgomp.c-c++-common/allocate-7.c
index 9968eb19005..8d5429b0eb3 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/allocate-7.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-7.c
@@ -1,9 +1,12 @@
-/* { dg-do run } */
+/* { dg-do run { target c } } */
+
+/* In C++, omp allocate in an omp::decl attribute is not currently supported.
*/
#include <omp.h>
int AAA [[omp::decl(allocate,allocator(omp_low_lat_mem_alloc),align(4096))]];
+
#ifndef __cplusplus
_Static_assert (_Alignof(AAA) == _Alignof(int), "wrong alignment");
#elif __cplusplus >= 201103L
--
2.54.0