Commit 2dc9294c by Jakub Jelinek

openmp: Reject requires directives not at file or namespace scope [PR94593]

This change started with a bugreport about a typo in one requires testcase
(diagnosed with -Wunknown-pragmas only), but following discussion lead to
noting that we do not diagnose restriction that requires directives in
C/C++ may only appear at file or namespace scope; and several our tests
violated that.

2020-04-15  Jakub Jelinek  <jakub@redhat.com>

	PR c/94593
	* c-parser.c (c_parser_pragma) <case PRAGMA_OMP_REQUIRES>: Reject
	requires directive when not at file scope.

	* parser.c (cp_parser_pragma) <case PRAGMA_OMP_REQUIRES>: Reject
	requires directive when not at file or namespace scope.

	* c-c++-common/gomp/requires-1.c: Fix a typo, requries -> requires.
	Move directives to file scope.
	(i): Remove.
	* c-c++-common/gomp/requires-2.c: Move directives to file scope.
	(i, foo): Remove.
	* c-c++-common/gomp/requires-4.c: Move directives to file scope.
	* c-c++-common/gomp/atomic-19.c: Move requires directive to file scope.
	* c-c++-common/gomp/atomic-20.c: Likewise.
	* c-c++-common/gomp/atomic-21.c: Likewise.
	* c-c++-common/gomp/atomic-22.c: Likewise.
	* gcc.dg/gomp/requires-1.c: New test.
	* g++.dg/gomp/requires-1.C: New test.
	* g++.dg/gomp/requires-2.C: New test.
	* g++.dg/gomp/atomic-18.C: Move requires directive to file scope.
parent e71b408a
2020-04-15 Jakub Jelinek <jakub@redhat.com>
PR c/94593
* c-parser.c (c_parser_pragma) <case PRAGMA_OMP_REQUIRES>: Reject
requires directive when not at file scope.
2020-04-08 Tobias Burnus <tobias@codesourcery.com> 2020-04-08 Tobias Burnus <tobias@codesourcery.com>
PR middle-end/94120 PR middle-end/94120
......
...@@ -12402,6 +12402,13 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p) ...@@ -12402,6 +12402,13 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
return false; return false;
case PRAGMA_OMP_REQUIRES: case PRAGMA_OMP_REQUIRES:
if (context != pragma_external)
{
error_at (c_parser_peek_token (parser)->location,
"%<#pragma omp requires%> may only be used at file scope");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
}
c_parser_omp_requires (parser); c_parser_omp_requires (parser);
return false; return false;
......
2020-04-15 Jakub Jelinek <jakub@redhat.com>
PR c/94593
* parser.c (cp_parser_pragma) <case PRAGMA_OMP_REQUIRES>: Reject
requires directive when not at file or namespace scope.
2020-04-14 Iain Sandoe <iain@sandoe.co.uk> 2020-04-14 Iain Sandoe <iain@sandoe.co.uk>
PR c++/94359 PR c++/94359
......
...@@ -43801,6 +43801,13 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p) ...@@ -43801,6 +43801,13 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
return true; return true;
case PRAGMA_OMP_REQUIRES: case PRAGMA_OMP_REQUIRES:
if (context != pragma_external)
{
error_at (pragma_tok->location,
"%<#pragma omp requires%> may only be used at file or "
"namespace scope");
break;
}
return cp_parser_omp_requires (parser, pragma_tok); return cp_parser_omp_requires (parser, pragma_tok);
case PRAGMA_OMP_ORDERED: case PRAGMA_OMP_ORDERED:
2020-04-15 Jakub Jelinek <jakub@redhat.com>
PR c/94593
* c-c++-common/gomp/requires-1.c: Fix a typo, requries -> requires.
Move directives to file scope.
(i): Remove.
* c-c++-common/gomp/requires-2.c: Move directives to file scope.
(i, foo): Remove.
* c-c++-common/gomp/requires-4.c: Move directives to file scope.
* gcc.dg/gomp/requires-1.c: New test.
* g++.dg/gomp/requires-1.C: New test.
* g++.dg/gomp/requires-2.C: New test.
2020-04-15 Richard Biener <rguenther@suse.de> 2020-04-15 Richard Biener <rguenther@suse.de>
PR middle-end/94539 PR middle-end/94539
......
...@@ -10,10 +10,16 @@ int i, j, k, l, m, n; ...@@ -10,10 +10,16 @@ int i, j, k, l, m, n;
void void
foo () foo ()
{ {
int v;
#pragma omp atomic release #pragma omp atomic release
i = i + 1; i = i + 1;
#pragma omp requires atomic_default_mem_order (relaxed) }
#pragma omp requires atomic_default_mem_order (relaxed)
void
bar ()
{
int v;
#pragma omp atomic #pragma omp atomic
j = j + 1; j = j + 1;
#pragma omp atomic update #pragma omp atomic update
......
...@@ -10,10 +10,16 @@ int i, j, k, l, m, n; ...@@ -10,10 +10,16 @@ int i, j, k, l, m, n;
void void
foo () foo ()
{ {
int v;
#pragma omp atomic release #pragma omp atomic release
i = i + 1; i = i + 1;
#pragma omp requires atomic_default_mem_order (seq_cst) }
#pragma omp requires atomic_default_mem_order (seq_cst)
void
bar ()
{
int v;
#pragma omp atomic #pragma omp atomic
j = j + 1; j = j + 1;
#pragma omp atomic update #pragma omp atomic update
......
...@@ -9,10 +9,16 @@ int i, j, k, l, m, n; ...@@ -9,10 +9,16 @@ int i, j, k, l, m, n;
void void
foo () foo ()
{ {
int v;
#pragma omp atomic release #pragma omp atomic release
i = i + 1; i = i + 1;
#pragma omp requires atomic_default_mem_order (acq_rel) }
#pragma omp requires atomic_default_mem_order (acq_rel)
void
bar ()
{
int v;
#pragma omp atomic #pragma omp atomic
j = j + 1; j = j + 1;
#pragma omp atomic update #pragma omp atomic update
......
...@@ -8,5 +8,6 @@ foo () ...@@ -8,5 +8,6 @@ foo ()
i = i + 1; i = i + 1;
#pragma omp atomic read #pragma omp atomic read
v = j; v = j;
#pragma omp requires atomic_default_mem_order (acq_rel) /* { dg-error "'atomic_default_mem_order' clause used lexically after first 'atomic' construct without memory order clause" } */
} }
#pragma omp requires atomic_default_mem_order (acq_rel) /* { dg-error "'atomic_default_mem_order' clause used lexically after first 'atomic' construct without memory order clause" } */
...@@ -3,15 +3,12 @@ ...@@ -3,15 +3,12 @@
#pragma omp requires unified_shared_memory unified_address #pragma omp requires unified_shared_memory unified_address
#pragma omp requires dynamic_allocators,reverse_offload #pragma omp requires dynamic_allocators,reverse_offload
int i;
void void
foo () foo ()
{ {
if (0)
#pragma omp requires unified_shared_memory unified_address
i++;
#pragma omp requries atomic_default_mem_order(seq_cst)
} }
#pragma omp requires unified_shared_memory unified_address
#pragma omp requires atomic_default_mem_order(seq_cst)
/* { dg-prune-output "not supported yet" } */ /* { dg-prune-output "not supported yet" } */
...@@ -3,18 +3,8 @@ ...@@ -3,18 +3,8 @@
#pragma omp requires unified_address unified_address /* { dg-error "too many 'unified_address' clauses" } */ #pragma omp requires unified_address unified_address /* { dg-error "too many 'unified_address' clauses" } */
#pragma omp requires reverse_offload reverse_offload /* { dg-error "too many 'reverse_offload' clauses" } */ #pragma omp requires reverse_offload reverse_offload /* { dg-error "too many 'reverse_offload' clauses" } */
#pragma omp requires foobarbaz /* { dg-error "expected 'unified_address', 'unified_shared_memory', 'dynamic_allocators', 'reverse_offload' or 'atomic_default_mem_order' clause" } */ #pragma omp requires foobarbaz /* { dg-error "expected 'unified_address', 'unified_shared_memory', 'dynamic_allocators', 'reverse_offload' or 'atomic_default_mem_order' clause" } */
#pragma omp requires dynamic_allocators , dynamic_allocators /* { dg-error "too many 'dynamic_allocators' clauses" } */
int i; #pragma omp requires atomic_default_mem_order(seq_cst) atomic_default_mem_order(seq_cst) /* { dg-error "too many 'atomic_default_mem_order' clauses" } */
void
foo ()
{
#pragma omp requires dynamic_allocators , dynamic_allocators /* { dg-error "too many 'dynamic_allocators' clauses" } */
if (0)
#pragma omp requires atomic_default_mem_order(seq_cst) atomic_default_mem_order(seq_cst) /* { dg-error "too many 'atomic_default_mem_order' clauses" } */
i++;
}
#pragma omp requires atomic_default_mem_order (seq_cst) /* { dg-error "more than one 'atomic_default_mem_order' clause in a single compilation unit" } */ #pragma omp requires atomic_default_mem_order (seq_cst) /* { dg-error "more than one 'atomic_default_mem_order' clause in a single compilation unit" } */
/* { dg-prune-output "not supported yet" } */ /* { dg-prune-output "not supported yet" } */
...@@ -4,9 +4,9 @@ foo (void) ...@@ -4,9 +4,9 @@ foo (void)
{ {
#pragma omp target #pragma omp target
; ;
#pragma omp requires unified_shared_memory /* { dg-error "'unified_shared_memory' clause used lexically after first target construct or offloading API" } */
} }
#pragma omp requires unified_shared_memory /* { dg-error "'unified_shared_memory' clause used lexically after first target construct or offloading API" } */
#pragma omp requires unified_address /* { dg-error "'unified_address' clause used lexically after first target construct or offloading API" } */ #pragma omp requires unified_address /* { dg-error "'unified_address' clause used lexically after first target construct or offloading API" } */
#pragma omp requires reverse_offload /* { dg-error "'reverse_offload' clause used lexically after first target construct or offloading API" } */ #pragma omp requires reverse_offload /* { dg-error "'reverse_offload' clause used lexically after first target construct or offloading API" } */
......
...@@ -36,7 +36,14 @@ foo (T *p) ...@@ -36,7 +36,14 @@ foo (T *p)
i = v; i = v;
#pragma omp atomic hint(1),update,release #pragma omp atomic hint(1),update,release
f = f + 2.0; f = f + 2.0;
#pragma omp requires atomic_default_mem_order (acq_rel) }
#pragma omp requires atomic_default_mem_order (acq_rel)
template <int N, int M, typename T>
void
baz (T *p)
{
#pragma omp atomic hint (M - 1) update #pragma omp atomic hint (M - 1) update
*p += 1; *p += 1;
#pragma omp atomic capture, hint (M) #pragma omp atomic capture, hint (M)
...@@ -47,4 +54,5 @@ void ...@@ -47,4 +54,5 @@ void
bar () bar ()
{ {
foo <0, 1, int> (&i); foo <0, 1, int> (&i);
baz <0, 1, int> (&i);
} }
namespace N {
namespace M {
#pragma omp requires unified_address
#pragma omp requires unified_shared_memory
#pragma omp requires unified_shared_memory unified_address
#pragma omp requires dynamic_allocators,reverse_offload
#pragma omp requires unified_shared_memory unified_address
#pragma omp requires atomic_default_mem_order(seq_cst)
}
}
/* { dg-prune-output "not supported yet" } */
int i;
void
foo ()
{
#pragma omp requires unified_address // { dg-error "may only be used at file or namespace scope" }
#pragma omp requires unified_shared_memory // { dg-error "may only be used at file or namespace scope" }
#pragma omp requires unified_shared_memory unified_address // { dg-error "may only be used at file or namespace scope" }
#pragma omp requires dynamic_allocators,reverse_offload // { dg-error "may only be used at file or namespace scope" }
#pragma omp requires atomic_default_mem_order(seq_cst) // { dg-error "may only be used at file or namespace scope" }
if (0)
#pragma omp requires unified_address // { dg-error "may only be used at file or namespace scope" }
i++;
if (0)
#pragma omp requires atomic_default_mem_order(seq_cst) // { dg-error "may only be used at file or namespace scope" }
i++;
}
struct S {
int s;
#pragma omp requires unified_address // { dg-error "may only be used at file or namespace scope" }
};
int i;
void
foo ()
{
#pragma omp requires unified_address /* { dg-error "may only be used at file scope" } */
#pragma omp requires unified_shared_memory /* { dg-error "may only be used at file scope" } */
#pragma omp requires unified_shared_memory unified_address /* { dg-error "may only be used at file scope" } */
#pragma omp requires dynamic_allocators,reverse_offload /* { dg-error "may only be used at file scope" } */
#pragma omp requires atomic_default_mem_order(seq_cst) /* { dg-error "may only be used at file scope" } */
if (0)
#pragma omp requires unified_address /* { dg-error "may only be used at file scope" } */
i++;
if (0)
#pragma omp requires atomic_default_mem_order(seq_cst) /* { dg-error "may only be used at file scope" } */
i++;
}
struct S {
int s;
#pragma omp requires unified_address /* { dg-error "may only be used at file scope" } */
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment