Hi!

expr2 for atomic write or swap is not something we want to take appart, we
just want to expand it as an rvalue as is, so we shouldn't be skipping its
conversions.  And, for the other cases, the patch adds function.isym check
so that we don't ICE if there is a call to an external function rather than
internal.

Tested on x86_64-linux, committed to trunk so far.

2016-09-08  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/77500
        * trans-openmp.c (gfc_trans_omp_atomic): For atomic write or
        swap, don't try to look through GFC_ISYM_CONVERSION.  In other cases,
        check that value.function.isym is non-NULL before dereferencing it.

        * gfortran.dg/gomp/pr77500.f90: New test.

--- gcc/fortran/trans-openmp.c.jj       2016-09-06 20:00:37.000000000 +0200
+++ gcc/fortran/trans-openmp.c  2016-09-08 12:24:13.112540373 +0200
@@ -2818,7 +2818,11 @@ gfc_trans_omp_atomic (gfc_code *code)
   gfc_start_block (&block);
 
   expr2 = code->expr2;
-  if (expr2->expr_type == EXPR_FUNCTION
+  if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
+       != GFC_OMP_ATOMIC_WRITE)
+      && (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP) == 0
+      && expr2->expr_type == EXPR_FUNCTION
+      && expr2->value.function.isym
       && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
     expr2 = expr2->value.function.actual->expr;
 
@@ -2857,6 +2861,7 @@ gfc_trans_omp_atomic (gfc_code *code)
          var = code->expr1->symtree->n.sym;
          expr2 = code->expr2;
          if (expr2->expr_type == EXPR_FUNCTION
+             && expr2->value.function.isym
              && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
            expr2 = expr2->value.function.actual->expr;
        }
@@ -2914,6 +2919,7 @@ gfc_trans_omp_atomic (gfc_code *code)
        }
       e = expr2->value.op.op1;
       if (e->expr_type == EXPR_FUNCTION
+         && e->value.function.isym
          && e->value.function.isym->id == GFC_ISYM_CONVERSION)
        e = e->value.function.actual->expr;
       if (e->expr_type == EXPR_VARIABLE
@@ -2927,6 +2933,7 @@ gfc_trans_omp_atomic (gfc_code *code)
        {
          e = expr2->value.op.op2;
          if (e->expr_type == EXPR_FUNCTION
+             && e->value.function.isym
              && e->value.function.isym->id == GFC_ISYM_CONVERSION)
            e = e->value.function.actual->expr;
          gcc_assert (e->expr_type == EXPR_VARIABLE
@@ -3041,6 +3048,7 @@ gfc_trans_omp_atomic (gfc_code *code)
          code = code->next;
          expr2 = code->expr2;
          if (expr2->expr_type == EXPR_FUNCTION
+             && expr2->value.function.isym
              && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
            expr2 = expr2->value.function.actual->expr;
 
--- gcc/testsuite/gfortran.dg/gomp/pr77500.f90.jj       2016-09-08 
12:36:11.252253375 +0200
+++ gcc/testsuite/gfortran.dg/gomp/pr77500.f90  2016-09-08 12:30:50.000000000 
+0200
@@ -0,0 +1,9 @@
+! PR fortran/77500
+! { dg-do compile }
+
+program pr77500
+   real :: x
+!$omp atomic write
+   x = f()
+!$omp end atomic
+end

        Jakub

Reply via email to