https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114024

Mikael Morin <mikael at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mikael at gcc dot gnu.org

--- Comment #7 from Mikael Morin <mikael at gcc dot gnu.org> ---
The fix causes a regression, see PR128033.

I'm revisiting this PR.

The problem comes from the sourced allocation handling in gfc_array_allocate.
We first find the last array reference (in the standard wording it is the array
spec) from the reference to allocate:
  6530    /* Find the last reference in the chain.  */
  6531    if (!retrieve_last_ref (&ref, &prev_ref))
  6532      return false;

and if none is found, get the array ref from the source expression:
  6568    if (ref->u.ar.type == AR_FULL && expr3 != NULL)
  6569      {
  6570        gfc_ref *old_ref = ref;
  6571        /* F08:C633: Array shape from expr3.  */
  6572        ref = expr3->ref;
  6573  
  6574        /* Find the last reference in the chain.  */
  6575        if (!retrieve_last_ref (&ref, &prev_ref))
  6576          {
  6577            if (expr3->expr_type == EXPR_FUNCTION
  6578                && gfc_expr_attr (expr3).dimension)
  6579              ref = old_ref;
  6580            else
  6581              return false;
  6582          }
  6583        alloc_w_e3_arr_spec = true;
  6584      }

The ICE is a failed assert in the main loop of retrieve_last_ref:
  6469    while (ref && ref->next != NULL)
  6470      {
  6471        gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type ==
AR_ELEMENT
  6472                    || (ref->u.ar.dimen == 0 && ref->u.ar.codimen > 0));
  6473        prev_ref = ref;
  6474        ref = ref->next;
  6475      }

This assert makes sense in the context of the first call to retrieve_last_ref,
because anything that comes before the array spec has to be scalar.  And when
we come to the array spec, that's the last reference in the chain and it's the
end of the loop.  For the second call of the function, we are not looking for
an array spec, but for an array ref, and those can have subreferences after
them.  So the second call is not looking for the last reference in the chain
but for the single non-element array ref.  It is a different need, so it should
be done by a different function.

Reply via email to