diff options
author | Tobias Burnus <tobias@codesourcery.com> | 2020-11-02 13:07:17 +0100 |
---|---|---|
committer | Tobias Burnus <tobias@codesourcery.com> | 2020-11-02 13:07:17 +0100 |
commit | b2a31e2c341d96520c5fb7c1e1f1c590eb182d7f (patch) | |
tree | c327731b11ce29bf629946aa13ad248e22a3f1b9 /gcc/fortran/openmp.c | |
parent | 4c198ddff83744f8b7bf24306ed1e6b889c44044 (diff) | |
download | gcc-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.c | 20 |
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); |