diff options
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); |