aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2023-11-24 15:10:49 +0100
committerTobias Burnus <tobias@codesourcery.com>2023-11-24 15:10:49 +0100
commit1802f64e674eeef0c0d7e8f6ca2846145ec16315 (patch)
treee68838cde627c0e9a342e2ad2495a826d024fb88 /gcc
parent726723c476800285cfbdfce612cedde4a9a7ad58 (diff)
downloadgcc-1802f64e674eeef0c0d7e8f6ca2846145ec16315.zip
gcc-1802f64e674eeef0c0d7e8f6ca2846145ec16315.tar.gz
gcc-1802f64e674eeef0c0d7e8f6ca2846145ec16315.tar.bz2
OpenMP: Accept argument to depobj's destroy clause
Since OpenMP 5.2, the destroy clause takes an depend argument as argument; for the depobj directive, it the new argument is optional but, if present, it must be identical to the directive's argument. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_depobj): Accept optionally an argument to the destroy clause. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_depobj): Accept optionally an argument to the destroy clause. gcc/fortran/ChangeLog: * openmp.cc (gfc_match_omp_depobj): Accept optionally an argument to the destroy clause. libgomp/ChangeLog: * libgomp.texi (5.2 Impl. Status): An argument to the destroy clause is now supported. gcc/testsuite/ChangeLog: * c-c++-common/gomp/depobj-3.c: New test. * gfortran.dg/gomp/depobj-3.f90: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/c-parser.cc24
-rw-r--r--gcc/cp/parser.cc25
-rw-r--r--gcc/fortran/openmp.cc12
-rw-r--r--gcc/testsuite/c-c++-common/gomp/depobj-3.c47
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/depobj-3.f9018
5 files changed, 123 insertions, 3 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 371dd29..989c050 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -21605,6 +21605,9 @@ c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
destroy
update (dependence-type)
+ OpenMP 5.2 additionally:
+ destroy ( depobj )
+
dependence-type:
in
out
@@ -21663,7 +21666,26 @@ c_parser_omp_depobj (c_parser *parser)
clause = error_mark_node;
}
else if (!strcmp ("destroy", p))
- kind = OMP_CLAUSE_DEPEND_LAST;
+ {
+ matching_parens c_parens;
+ kind = OMP_CLAUSE_DEPEND_LAST;
+ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
+ && c_parens.require_open (parser))
+ {
+ tree destobj = c_parser_expr_no_commas (parser, NULL).value;
+ if (!lvalue_p (destobj))
+ error_at (EXPR_LOC_OR_LOC (destobj, c_loc),
+ "%<destroy%> expression is not lvalue expression");
+ else if (depobj != error_mark_node
+ && !operand_equal_p (destobj, depobj,
+ OEP_MATCH_SIDE_EFFECTS
+ | OEP_LEXICOGRAPHIC))
+ warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), 0,
+ "the %<destroy%> expression %qE should be the same "
+ "as the %<depobj%> argument %qE", destobj, depobj);
+ c_parens.skip_until_found_close (parser);
+ }
+ }
else if (!strcmp ("update", p))
{
matching_parens c_parens;
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f6d088b..e4e2fea 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -43173,6 +43173,9 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
destroy
update (dependence-type)
+ OpenMP 5.2 additionally:
+ destroy ( depobj )
+
dependence-type:
in
out
@@ -43219,7 +43222,27 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
clause = error_mark_node;
}
else if (!strcmp ("destroy", p))
- kind = OMP_CLAUSE_DEPEND_LAST;
+ {
+ kind = OMP_CLAUSE_DEPEND_LAST;
+ matching_parens c_parens;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ && c_parens.require_open (parser))
+ {
+ tree destobj = cp_parser_assignment_expression (parser);
+ if (depobj != error_mark_node
+ && destobj != error_mark_node
+ && !operand_equal_p (destobj, depobj, OEP_MATCH_SIDE_EFFECTS
+ | OEP_LEXICOGRAPHIC))
+ warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), 0,
+ "the %<destroy%> expression %qE should be the same "
+ "as the %<depobj%> argument %qE", destobj, depobj);
+ if (!c_parens.require_close (parser))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ }
+ }
else if (!strcmp ("update", p))
{
matching_parens c_parens;
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 2e2e23d..b9ac611 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -4731,10 +4731,20 @@ gfc_match_omp_depobj (void)
goto error;
}
}
- else if (gfc_match ("destroy") == MATCH_YES)
+ else if (gfc_match ("destroy ") == MATCH_YES)
{
+ gfc_expr *destroyobj = NULL;
c = gfc_get_omp_clauses ();
c->destroy = true;
+
+ if (gfc_match (" ( %v ) ", &destroyobj) == MATCH_YES)
+ {
+ if (destroyobj->symtree != depobj->symtree)
+ gfc_warning (0, "The same depend object should be used as DEPOBJ "
+ "argument at %L and as DESTROY argument at %L",
+ &depobj->where, &destroyobj->where);
+ gfc_free_expr (destroyobj);
+ }
}
else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_DEPEND), true, false)
!= MATCH_YES)
diff --git a/gcc/testsuite/c-c++-common/gomp/depobj-3.c b/gcc/testsuite/c-c++-common/gomp/depobj-3.c
new file mode 100644
index 0000000..a5017a4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/depobj-3.c
@@ -0,0 +1,47 @@
+typedef struct __attribute__((__aligned__ (sizeof (void *)))) omp_depend_t {
+ char __omp_depend_t__[2 * sizeof (void *)];
+} omp_depend_t;
+
+void
+f ()
+{
+ omp_depend_t obj2;
+ struct { omp_depend_t c; } s;
+ float a;
+ #pragma omp depobj(s.c) depend(inout: a)
+
+ #pragma omp depobj(s.c) destroy(s.c) /* OK */
+
+ #pragma omp depobj(s.c) destroy(obj2)
+/* { dg-warning "the 'destroy' expression 'obj2' should be the same as the 'depobj' argument 's.c'" "" { target c } .-1 } */
+/* { dg-warning "the 'destroy' expression 'obj2' should be the same as the 'depobj' argument 's.f\\(\\)::<unnamed struct>::c'" "" { target c++ } .-2 } */
+}
+
+void
+g ()
+{
+ volatile omp_depend_t obj3;
+ #pragma omp depobj(obj3) destroy(obj3)
+}
+
+int
+main ()
+{
+ float a;
+ omp_depend_t obj;
+
+ #pragma omp depobj(obj) depend(inout: a)
+
+ #pragma omp depobj(obj) destroy(obj) /* OK */
+
+ #pragma omp depobj(obj) destroy(a + 5)
+/* { dg-error "'destroy' expression is not lvalue expression" "" { target c } .-1 } */
+/* { dg-warning "the 'destroy' expression '\\(a \\+ \\(float\\)5\\)' should be the same as the 'depobj' argument 'obj'" "" { target c++ } .-2 } */
+
+ #pragma omp depobj(obj+5) destroy(a)
+/* { dg-error "invalid operands to binary \\+ \\(have 'omp_depend_t' and 'int'\\)" "" { target c } .-1 } */
+/* { dg-error "no match for 'operator\\+' in 'obj \\+ 5' \\(operand types are 'omp_depend_t' and 'int'\\)" "" { target c++ } .-2 } */
+
+ #pragma omp depobj(obj) destroy(a) /* { dg-warning "the 'destroy' expression 'a' should be the same as the 'depobj' argument 'obj'" } */
+ return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/gomp/depobj-3.f90 b/gcc/testsuite/gfortran.dg/gomp/depobj-3.f90
new file mode 100644
index 0000000..8a3625e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/depobj-3.f90
@@ -0,0 +1,18 @@
+! { dg-do compile { target { fortran_integer_16 || ilp32 } } }
+! omp_depend_kind = 2*intptr_t --> 16 (128 bit) on 64bit-pointer systems
+! --> 8 (128 bit) on 32bit-pointer systems
+subroutine f1
+ !use omp_lib ! N/A in gcc/testsuite
+ use iso_c_binding, only: c_intptr_t
+ implicit none
+ integer, parameter :: omp_depend_kind = 2*c_intptr_t
+ integer :: a, b
+ integer(kind=omp_depend_kind) :: depobj, depobj1(5), depobj2
+
+ !$omp depobj(depobj) destroy
+
+ !$omp depobj(depobj) destroy( depobj)
+
+ !$omp depobj(depobj) destroy( depobj2) ! { dg-warning "The same depend object should be used as DEPOBJ argument at .1. and as DESTROY argument at .2." }
+ !$omp depobj(depobj) destroy( a) ! { dg-warning "The same depend object should be used as DEPOBJ argument at .1. and as DESTROY argument at .2." }
+end