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

--- Comment #21 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Mikael Morin <mik...@gcc.gnu.org>:

https://gcc.gnu.org/g:9206641d0899e4bae3ad6765129661ff3bcc423a

commit r14-2521-g9206641d0899e4bae3ad6765129661ff3bcc423a
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri Jul 14 14:15:51 2023 +0200

    fortran: Reorder array argument evaluation parts [PR92178]

    In the case of an array actual arg passed to a polymorphic array dummy
    with INTENT(OUT) attribute, reorder the argument evaluation code to
    the following:
     - first evaluate arguments' values, and data references,
     - deallocate data references associated with an allocatable,
       intent(out) dummy,
     - create a class container using the freed data references.

    The ordering used to be incorrect between the first two items,
    when one argument was deallocated before a later argument evaluated
    its expression depending on the former argument.
    r14-2395-gb1079fc88f082d3c5b583c8822c08c5647810259 fixed it by treating
    arguments associated with an allocatable, intent(out) dummy in a
    separate, later block.  This, however, wasn't working either if the data
    reference of such an argument was depending on its own content, as
    the class container initialization was trying to use deallocated
    content.

    This change generates class container initialization code in a separate
    block, so that it is moved after the deallocation block without moving
    the rest of the argument evaluation code.

    This alone is not sufficient to fix the problem, because the class
    container generation code repeatedly uses the full expression of
    the argument at a place where deallocation might have happened
    already.  This is non-optimal, but may also be invalid, because the data
    reference may depend on its own content.  In that case the expression
    can't be evaluated after the data has been deallocated.

    As in the scalar case previously treated, this is fixed by saving
    the data reference to a pointer before any deallocation happens,
    and then only refering to the pointer.  gfc_reset_vptr is updated
    to take into account the already evaluated class container if it's
    available.

    Contrary to the scalar case, one hunk is needed to wrap the parameter
    evaluation in a conditional, to avoid regressing in
    optional_class_2.f90.  This used to be handled by the class wrapper
    construction which wrapped the whole code in a conditional.  With
    this change the class wrapper construction can't see the parameter
    evaluation code, so the latter is updated with an additional handling
    for optional arguments.

            PR fortran/92178

    gcc/fortran/ChangeLog:

            * trans.h (gfc_reset_vptr): Add class_container argument.
            * trans-expr.cc (gfc_reset_vptr): Ditto.  If a valid vptr can
            be obtained through class_container argument, bypass evaluation
            of e.
            (gfc_conv_procedure_call):  Wrap the argument evaluation code
            in a conditional if the associated dummy is optional.  Evaluate
            the data reference to a pointer now, and replace later
            references with usage of the pointer.

    gcc/testsuite/ChangeLog:

            * gfortran.dg/intent_out_21.f90: New test.

Reply via email to