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