+2016-08-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/77374
+ * parse.c (parse_omp_oacc_atomic): Copy over cp->ext.omp_atomic
+ to cp->block->ext.omp_atomic.
+ * resolve.c (gfc_resolve_blocks): Assert block with one or two
+ EXEC_ASSIGNs for EXEC_*_ATOMIC.
+ * openmp.c (resolve_omp_atomic): Don't assert one or two
+ EXEC_ASSIGNs, instead return quietly for EXEC_NOPs and otherwise
+ error unexpected statements.
+
2016-08-31 Paul Thomas <pault@gcc.gnu.org>
- Jerry DeLisle <jvdelisle@gcc.gnu.org>
+ Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/48298
-
* decl.c (access_attr_decl): Include case INTERFACE_DTIO as
appropriate.
* gfortran.h : Add INTRINSIC_FORMATTED and
= (gfc_omp_atomic_op) (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK);
code = code->block->next;
- gcc_assert (code->op == EXEC_ASSIGN);
- gcc_assert (((aop != GFC_OMP_ATOMIC_CAPTURE) && code->next == NULL)
- || ((aop == GFC_OMP_ATOMIC_CAPTURE)
- && code->next != NULL
- && code->next->op == EXEC_ASSIGN
- && code->next->next == NULL));
+ /* resolve_blocks asserts this is initially EXEC_ASSIGN.
+ If it changed to EXEC_NOP, assume an error has been emitted already. */
+ if (code->op == EXEC_NOP)
+ return;
+ if (code->op != EXEC_ASSIGN)
+ {
+ unexpected:
+ gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code->loc);
+ return;
+ }
+ if (aop != GFC_OMP_ATOMIC_CAPTURE)
+ {
+ if (code->next != NULL)
+ goto unexpected;
+ }
+ else
+ {
+ if (code->next == NULL)
+ goto unexpected;
+ if (code->next->op == EXEC_NOP)
+ return;
+ if (code->next->op != EXEC_ASSIGN || code->next->next)
+ {
+ code = code->next;
+ goto unexpected;
+ }
+ }
if (code->expr1->expr_type != EXPR_VARIABLE
|| code->expr1->symtree == NULL
np = new_level (cp);
np->op = cp->op;
np->block = NULL;
+ np->ext.omp_atomic = cp->ext.omp_atomic;
count = 1 + ((cp->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
== GFC_OMP_ATOMIC_CAPTURE);
case EXEC_WAIT:
break;
+ case EXEC_OMP_ATOMIC:
+ case EXEC_OACC_ATOMIC:
+ {
+ gfc_omp_atomic_op aop
+ = (gfc_omp_atomic_op) (b->ext.omp_atomic & GFC_OMP_ATOMIC_MASK);
+
+ /* Verify this before calling gfc_resolve_code, which might
+ change it. */
+ gcc_assert (b->next && b->next->op == EXEC_ASSIGN);
+ gcc_assert (((aop != GFC_OMP_ATOMIC_CAPTURE)
+ && b->next->next == NULL)
+ || ((aop == GFC_OMP_ATOMIC_CAPTURE)
+ && b->next->next != NULL
+ && b->next->next->op == EXEC_ASSIGN
+ && b->next->next->next == NULL));
+ }
+ break;
+
case EXEC_OACC_PARALLEL_LOOP:
case EXEC_OACC_PARALLEL:
case EXEC_OACC_KERNELS_LOOP:
case EXEC_OACC_CACHE:
case EXEC_OACC_ENTER_DATA:
case EXEC_OACC_EXIT_DATA:
- case EXEC_OACC_ATOMIC:
case EXEC_OACC_ROUTINE:
- case EXEC_OMP_ATOMIC:
case EXEC_OMP_CRITICAL:
case EXEC_OMP_DISTRIBUTE:
case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
+2016-08-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/77374
+ * gfortran.dg/gomp/pr77374.f08: New test.
+
2016-08-31 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/73714
intended item on the stack.
2016-08-31 Jerry DeLisle <jvdelisle@gcc.gnu.org>
- Paul Thomas <pault@gcc.gnu.org>
+ Paul Thomas <pault@gcc.gnu.org>
PR fortran/48298
* gfortran.dg/dtio_1.f90: New test.
--- /dev/null
+! PR fortran/77374
+! { dg-do compile }
+
+subroutine foo (a, b)
+ integer :: a, b
+!$omp atomic
+ b = b + a
+!$omp atomic
+ z(1) = z(1) + 1 ! { dg-error "must have the pointer attribute" }
+end subroutine
+subroutine bar (a, b)
+ integer :: a, b
+ interface
+ function baz (i) result (res)
+ integer, pointer :: res
+ integer :: i
+ end function
+ end interface
+!$omp atomic
+ baz (i) = 1 ! { dg-error "unexpected" }
+end subroutine