aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/openmp.c
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2020-11-02 13:07:17 +0100
committerTobias Burnus <tobias@codesourcery.com>2020-11-02 13:07:17 +0100
commitb2a31e2c341d96520c5fb7c1e1f1c590eb182d7f (patch)
treec327731b11ce29bf629946aa13ad248e22a3f1b9 /gcc/fortran/openmp.c
parent4c198ddff83744f8b7bf24306ed1e6b889c44044 (diff)
downloadgcc-b2a31e2c341d96520c5fb7c1e1f1c590eb182d7f.zip
gcc-b2a31e2c341d96520c5fb7c1e1f1c590eb182d7f.tar.gz
gcc-b2a31e2c341d96520c5fb7c1e1f1c590eb182d7f.tar.bz2
Fortran: OpenMP - fixes for omp atomic [PR97655]
gcc/fortran/ChangeLog: PR fortran/97655 * openmp.c (gfc_match_omp_atomic): Fix mem-order handling; reject specifying update + capture together. gcc/testsuite/ChangeLog: PR fortran/97655 * gfortran.dg/gomp/atomic.f90: Update tree-dump counts; move invalid OMP 5.0 code to ... * gfortran.dg/gomp/atomic-2.f90: ... here; update dg-error. * gfortran.dg/gomp/requires-9.f90: Update tree dump scan.
Diffstat (limited to 'gcc/fortran/openmp.c')
-rw-r--r--gcc/fortran/openmp.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 608ff5a..6cb4f28 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -4107,12 +4107,13 @@ gfc_match_omp_atomic (void)
if (gfc_match_omp_clauses (&c, OMP_ATOMIC_CLAUSES, true, true) != MATCH_YES)
return MATCH_ERROR;
+
+ if (c->capture && c->atomic_op != GFC_OMP_ATOMIC_UNSET)
+ gfc_error ("OMP ATOMIC at %L with multiple atomic clauses", &loc);
+
if (c->atomic_op == GFC_OMP_ATOMIC_UNSET)
c->atomic_op = GFC_OMP_ATOMIC_UPDATE;
- if (c->capture && c->atomic_op != GFC_OMP_ATOMIC_UPDATE)
- gfc_error ("OMP ATOMIC at %L with CAPTURE clause must be UPDATE", &loc);
-
if (c->memorder == OMP_MEMORDER_UNSET)
{
gfc_namespace *prog_unit = gfc_current_ns;
@@ -4128,12 +4129,12 @@ gfc_match_omp_atomic (void)
c->memorder = OMP_MEMORDER_SEQ_CST;
break;
case OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL:
- if (c->atomic_op == GFC_OMP_ATOMIC_READ)
- c->memorder = OMP_MEMORDER_ACQUIRE;
+ if (c->capture)
+ c->memorder = OMP_MEMORDER_ACQ_REL;
else if (c->atomic_op == GFC_OMP_ATOMIC_READ)
- c->memorder = OMP_MEMORDER_RELEASE;
+ c->memorder = OMP_MEMORDER_ACQUIRE;
else
- c->memorder = OMP_MEMORDER_ACQ_REL;
+ c->memorder = OMP_MEMORDER_RELEASE;
break;
default:
gcc_unreachable ();
@@ -4161,8 +4162,9 @@ gfc_match_omp_atomic (void)
}
break;
case GFC_OMP_ATOMIC_UPDATE:
- if (c->memorder == OMP_MEMORDER_ACQ_REL
- || c->memorder == OMP_MEMORDER_ACQUIRE)
+ if ((c->memorder == OMP_MEMORDER_ACQ_REL
+ || c->memorder == OMP_MEMORDER_ACQUIRE)
+ && !c->capture)
{
gfc_error ("!$OMP ATOMIC UPDATE at %L incompatible with "
"ACQ_REL or ACQUIRE clauses", &loc);