Hi Tomáš,

one small nit: I would prefer to use i = -1 as the initializer for component of
the derived type, because 0 is a default generated one and that way one can
distinguish them. With that, ok for mainline and thanks for the patch.

- Andre

On Wed, 25 Sep 2024 17:20:12 +0200
Tomáš Trnka <tr...@scm.com> wrote:

> This fixes PR fortran/116829 by making sure that s->value is always
> applied to non-allocatable BT_DERIVED intent(out) arguments, no matter
> if they are finalizable or not.
> 
> Tested on x86_64-pc-linux-gnu (Fedora 40), any feedback is welcome.
> 
> gcc/fortran/ChangeLog:
> 
>         * trans-decl.cc (init_intent_out_dt): Always call
>         gfc_init_default_dt() for BT_DERIVED to apply s->value
>         if the symbol isn't allocatable. Also simplify the logic a bit.
> 
> gcc/testsuite/ChangeLog:
> 
>         * gfortran.dg/derived_init_7.f90: New test.
> 
> Signed-off-by: Tomáš Trnka <tr...@scm.com>
> ---
>  gcc/fortran/trans-decl.cc                    |  9 +---
>  gcc/testsuite/gfortran.dg/derived_init_7.f90 | 49 ++++++++++++++++++++
>  2 files changed, 51 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/gfortran.dg/derived_init_7.f90
> 
> diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
> index 8231bd255d6..50e8adcb819 100644
> --- a/gcc/fortran/trans-decl.cc
> +++ b/gcc/fortran/trans-decl.cc
> @@ -4461,7 +4461,6 @@ init_intent_out_dt (gfc_symbol * proc_sym,
> gfc_wrapped_block * block) tree tmp;
>    tree present;
>    gfc_symbol *s;
> -  bool dealloc_with_value = false;
>  
>    gfc_init_block (&init);
>    for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
> @@ -4496,7 +4495,6 @@ init_intent_out_dt (gfc_symbol * proc_sym,
> gfc_wrapped_block * block) tmp = gfc_deallocate_alloc_comp (s->ts.u.derived,
>                                            s->backend_decl,
>                                            s->as ? s->as->rank : 0);
> -         dealloc_with_value = s->value;
>         }
>  
>       if (tmp != NULL_TREE && (s->attr.optional
> @@ -4507,13 +4505,10 @@ init_intent_out_dt (gfc_symbol * proc_sym,
> gfc_wrapped_block * block) present, tmp, build_empty_stmt (input_location));
>         }
>  
> -     if (tmp != NULL_TREE && !dealloc_with_value)
> -       gfc_add_expr_to_block (&init, tmp);
> -     else if (s->value && !s->attr.allocatable)
> +     gfc_add_expr_to_block (&init, tmp);
> +     if (s->value && !s->attr.allocatable)
>         {
> -         gfc_add_expr_to_block (&init, tmp);
>           gfc_init_default_dt (s, &init, false);
> -         dealloc_with_value = false;
>         }
>        }
>      else if (f->sym && f->sym->attr.intent == INTENT_OUT
> diff --git a/gcc/testsuite/gfortran.dg/derived_init_7.f90
> b/gcc/testsuite/gfortran.dg/derived_init_7.f90 new file mode 100644
> index 00000000000..8efb7ba1c77
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/derived_init_7.f90
> @@ -0,0 +1,49 @@
> +! { dg-do run }
> +! Check that finalizable intent(out) dummy arguments are first finalized
> +! and then correctly default-initialized (PR116829)
> +!
> +module FinalizableIntentOutTestModule
> +   implicit none
> +
> +   type :: AapType
> +      integer  :: i = 0
> +   contains
> +      final    :: Finalizer
> +   end type
> +
> +contains
> +
> +   subroutine Finalizer(self)
> +      type(AapType), intent(inout) :: self
> +
> +      ! Fail if Finalizer gets called again on an already finalized object
> +      if (self%i == 42) stop 1
> +
> +      self%i = 42 ! Nobody should ever see this value after finalization
> +   end subroutine
> +
> +end module
> +
> +
> +program test
> +   use FinalizableIntentOutTestModule
> +
> +   implicit none
> +
> +   type(AapType) :: aap
> +
> +   ! Set "i" to nonzero so that initialization in MakeAap has something to do
> +   aap%i = 1
> +
> +   call MakeAap(aap)
> +
> +contains
> +
> +   subroutine MakeAap(a)
> +      type(AapType), intent(out) :: a
> +
> +      ! Fail if "a" wasn't initialized properly
> +      if (a%i /= 0) stop 2
> +   end subroutine
> +
> +end program


-- 
Andre Vehreschild * Email: vehre ad gmx dot de 

Reply via email to