aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2015-02-12 19:30:53 +0000
committerPaul Thomas <pault@gcc.gnu.org>2015-02-12 19:30:53 +0000
commitec6a7096e3da03d3f0b22878be007d54af6d137d (patch)
tree65515247139d8d4088e1b6ba93b4bbe760bc68eb /gcc/fortran
parent12d0d3581b0acf77d6cb57b6e77eaf92e0413b78 (diff)
downloadgcc-ec6a7096e3da03d3f0b22878be007d54af6d137d.zip
gcc-ec6a7096e3da03d3f0b22878be007d54af6d137d.tar.gz
gcc-ec6a7096e3da03d3f0b22878be007d54af6d137d.tar.bz2
re PR fortran/64932 (ICE in gfc_conv_descriptor_data_get for generated finalizer)
2015-02-12 Paul Thomas <pault@gcc.gnu.org> 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 <pault@gcc.gnu.org> PR fortran/64932 * gfortran.dg/finalize_28.f90: New test From-SVN: r220654
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/trans-stmt.c44
2 files changed, 47 insertions, 5 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index a884220..bff0cb6 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,11 @@
+2015-02-12 Paul Thomas <pault@gcc.gnu.org>
+
+ 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 <mikael@gcc.gnu.org>
PR fortran/63744
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 7e0e856..505f905 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);
}