Index: gcc/fortran/trans-expr.c =================================================================== *** gcc/fortran/trans-expr.c (revision 256000) --- gcc/fortran/trans-expr.c (working copy) *************** gfc_trans_assignment_1 (gfc_expr * expr1 *** 10076,10081 **** --- 10076,10103 ---- gfc_trans_runtime_check (true, false, cond, &loop.pre, &expr1->where, msg); } + + /* Deallocate the lhs parameterized components if required. */ + if (dealloc) + { + if (expr1->ts.type == BT_DERIVED + && expr1->ts.u.derived + && expr1->ts.u.derived->attr.pdt_type) + { + tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr, + expr1->rank); + gfc_add_expr_to_block (&lse.pre, tmp); + } + else if (expr1->ts.type == BT_CLASS + && CLASS_DATA (expr1)->ts.u.derived + && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type) + { + tmp = gfc_class_data_get (lse.expr); + tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived, + tmp, expr1->rank); + gfc_add_expr_to_block (&lse.pre, tmp); + } + } } /* Assignments of scalar derived types with allocatable components Index: gcc/fortran/trans-decl.c =================================================================== *** gcc/fortran/trans-decl.c (revision 256000) --- gcc/fortran/trans-decl.c (working copy) *************** gfc_trans_deferred_vars (gfc_symbol * pr *** 4344,4352 **** sym->as ? sym->as->rank : 0, sym->param_list); gfc_add_expr_to_block (&tmpblock, tmp); ! tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, ! sym->backend_decl, ! sym->as ? sym->as->rank : 0); gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp); } else if (sym->attr.dummy) --- 4344,4355 ---- sym->as ? sym->as->rank : 0, sym->param_list); gfc_add_expr_to_block (&tmpblock, tmp); ! if (!sym->attr.result) ! tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, ! sym->backend_decl, ! sym->as ? sym->as->rank : 0); ! else ! tmp = NULL_TREE; gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp); } else if (sym->attr.dummy) *************** gfc_trans_deferred_vars (gfc_symbol * pr *** 4376,4383 **** sym->param_list); gfc_add_expr_to_block (&tmpblock, tmp); tmp = gfc_class_data_get (sym->backend_decl); ! tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp, ! data->as ? data->as->rank : 0); gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp); } else if (sym->attr.dummy) --- 4379,4389 ---- sym->param_list); gfc_add_expr_to_block (&tmpblock, tmp); tmp = gfc_class_data_get (sym->backend_decl); ! if (!sym->attr.result) ! tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp, ! data->as ? data->as->rank : 0); ! else ! tmp = NULL_TREE; gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp); } else if (sym->attr.dummy) Index: gcc/testsuite/gfortran.dg/pdt_26.f03 =================================================================== *** gcc/testsuite/gfortran.dg/pdt_26.f03 (nonexistent) --- gcc/testsuite/gfortran.dg/pdt_26.f03 (working copy) *************** *** 0 **** --- 1,46 ---- + ! { dg-do run } + ! { dg-options "-fdump-tree-original" } + ! + ! Test the fix for PR83567 in which the parameterized component 'foo' was + ! being deallocated before return from 'addw', with consequent segfault in + ! the main program. + ! + ! Contributed by Berke Durak + ! The function 'addvv' has been made elemental so that the test can check that + ! arrays are correctly treated and that no memory leaks occur. + ! + module pdt_m + implicit none + type :: vec(k) + integer, len :: k=3 + integer :: foo(k)=[1,2,3] + end type vec + contains + elemental function addvv(a,b) result(c) + type(vec(k=*)), intent(in) :: a + type(vec(k=*)), intent(in) :: b + type(vec(k=a%k)) :: c + + c%foo=a%foo+b%foo + end function + end module pdt_m + + program test_pdt + use pdt_m + implicit none + type(vec) :: u,v,w, a(2), b(2), c(2) + integer :: i + + u%foo=[1,2,3] + v%foo=[2,3,4] + w=addvv(u,v) + if (any (w%foo .ne. [3,5,7])) call abort + do i = 1 , a(1)%k + a%foo(i) = i + 4 + b%foo(i) = i + 7 + end do + c = addvv(a,b) + if (any (c(1)%foo .ne. [13,15,17])) call abort + end program test_pdt + ! { dg-final { scan-tree-dump-times "__builtin_free" 8 "original" } } + ! { dg-final { scan-tree-dump-times "__builtin_malloc" 7 "original" } }