From ec6a7096e3da03d3f0b22878be007d54af6d137d Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Thu, 12 Feb 2015 19:30:53 +0000 Subject: [PATCH] re PR fortran/64932 (ICE in gfc_conv_descriptor_data_get for generated finalizer) 2015-02-12 Paul Thomas PR fortran/64932 * trans-stmt.c (gfc_trans_deallocate): If a component array expression is not a descriptor type and it is a derived type that has allocatable components and is not finalizable, then deallocate the allocatable components. 2015-02-12 Paul Thomas PR fortran/64932 * gfortran.dg/finalize_28.f90: New test From-SVN: r220654 --- gcc/fortran/ChangeLog | 8 +++++ gcc/fortran/trans-stmt.c | 44 ++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gfortran.dg/finalize_28.f90 | 24 +++++++++++++ 4 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/finalize_28.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a884220f21f..bff0cb6454a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2015-02-12 Paul Thomas + + PR fortran/64932 + * trans-stmt.c (gfc_trans_deallocate): If a component array + expression is not a descriptor type and it is a derived type + that has allocatable components and is not finalizable, then + deallocate the allocatable components. + 2015-02-08 Mikael Morin PR fortran/63744 diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 7e0e856b0d0..505f9052cf6 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -5575,11 +5575,13 @@ gfc_trans_deallocate (gfc_code *code) if (expr->rank || gfc_is_coarray (expr)) { + gfc_ref *ref; + if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp && !gfc_is_finalizable (expr->ts.u.derived, NULL)) { - gfc_ref *ref; gfc_ref *last = NULL; + for (ref = expr->ref; ref; ref = ref->next) if (ref->type == REF_COMPONENT) last = ref; @@ -5590,13 +5592,45 @@ gfc_trans_deallocate (gfc_code *code) && !(!last && expr->symtree->n.sym->attr.pointer)) { tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se.expr, - expr->rank); + expr->rank); gfc_add_expr_to_block (&se.pre, tmp); } } - tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen, - label_finish, expr); - gfc_add_expr_to_block (&se.pre, tmp); + + if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))) + { + tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen, + label_finish, expr); + gfc_add_expr_to_block (&se.pre, tmp); + } + else if (TREE_CODE (se.expr) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr))) + == RECORD_TYPE) + { + /* class.c(finalize_component) generates these, when a + finalizable entity has a non-allocatable derived type array + component, which has allocatable components. Obtain the + derived type of the array and deallocate the allocatable + components. */ + for (ref = expr->ref; ref; ref = ref->next) + { + if (ref->u.c.component->attr.dimension + && ref->u.c.component->ts.type == BT_DERIVED) + break; + } + + if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp + && !gfc_is_finalizable (ref->u.c.component->ts.u.derived, + NULL)) + { + tmp = gfc_deallocate_alloc_comp + (ref->u.c.component->ts.u.derived, + se.expr, expr->rank); + gfc_add_expr_to_block (&se.pre, tmp); + } + } + if (al->expr->ts.type == BT_CLASS) gfc_reset_vptr (&se.pre, al->expr); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3cb5af0c8ac..ef26e99d2d2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-02-12 Paul Thomas + + PR fortran/64932 + * gfortran.dg/finalize_28.f90: New test + 2015-02-12 Jakub Jelinek PR debug/55541 diff --git a/gcc/testsuite/gfortran.dg/finalize_28.f90 b/gcc/testsuite/gfortran.dg/finalize_28.f90 new file mode 100644 index 00000000000..03de5d0d28b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/finalize_28.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! Test the fix for PR64932. +! +! Reported by Daniel Shapiro +! +module coo_graphs + implicit none + type :: dynamic_array + integer :: length, capacity, min_capacity + integer, allocatable :: array(:) + end type + type :: coo_graph + type(dynamic_array) :: edges(2) + integer, private :: ne + end type coo_graph +contains + subroutine coo_dump_edges(g, edges) + class(coo_graph), intent(in) :: g + integer, intent(out) :: edges(:,:) + end subroutine coo_dump_edges +end module coo_graphs +! { dg-final { scan-tree-dump-times "__builtin_free" 3 "original" } } -- 2.30.2