When lowering an OpenMP depend clause with an iterator expression such as
x(j)%a, the front end currently looks only at the first REF_ARRAY to
decide between scalar-reference lowering and array-descriptor lowering.
For x(j)%a that first ref is the scalar base element x(j), but the full
expression is still the rank-1 component array a.
As a result, the code calls gfc_conv_expr_reference on an array-valued
expression, which later reaches gfc_conv_scalarized_array_ref without a
scalarizer state and ICEs.
Fix this by choosing the lowering path from the rank of the full
expression. Rank-zero expressions still use gfc_conv_expr_reference,
while array-valued expressions are lowered through gfc_conv_expr_descriptor.
Apply the same adjustment to the analogous depobj helper and add a
regression test for task depend clauses covering both x(j)%a and the
scalar control case x(j)%a(1).
gcc/fortran/ChangeLog:
PR fortran/102459
* trans-openmp.cc (gfc_trans_omp_clauses): Choose the scalar
reference path from the full expression rank rather than the first
array reference.
(gfc_trans_omp_depobj): Likewise.
gcc/testsuite/ChangeLog:
PR fortran/102459
* gfortran.dg/pr102459.f90: New test.
Signed-off-by: Christopher Albert <albert@tugraz.at>
{
tree ptr;
gfc_init_se (&se, NULL);
- if (n->expr->ref->u.ar.type == AR_ELEMENT)
+ /* The first ref can be an element selection on the base
+ object while the full expression still denotes an array,
+ e.g. x(j)%a. Pick the lowering path from the overall
+ expression rank, not from the first REF_ARRAY. */
+ if (n->expr->rank == 0)
{
gfc_conv_expr_reference (&se, n->expr);
ptr = se.expr;
else if (n->expr && n->expr->ref->u.ar.type != AR_FULL)
{
gfc_init_se (&se, NULL);
- if (n->expr->ref->u.ar.type == AR_ELEMENT)
+ if (n->expr->rank == 0)
{
gfc_conv_expr_reference (&se, n->expr);
var = se.expr;
--- /dev/null
+! { dg-do compile }
+! { dg-additional-options "-fopenmp" }
+
+program p
+ type t
+ integer :: a(2)
+ end type
+ type(t) :: x(8)
+
+ !$omp task depend (iterator(j=1:8), out:x(j)%a)
+ !$omp end task
+
+ !$omp task depend (iterator(j=1:8), out:x(j)%a(1))
+ !$omp end task
+end