From d897090949086d1a094429f043a4dcb7bbc74448 Mon Sep 17 00:00:00 2001 From: Andre Vehreschild Date: Mon, 9 Dec 2024 14:56:27 +0100 Subject: Fortran: Extend cylic type detection for deallocate [PR116669] Using cycles in derived/class types lead to the compiler doing a endless recursion in several locations, when the cycle was not immediate. An immediate cyclic dependency is present in, for example T T::comp. Cylcic dependencies of the form T T2::comp; T2 T::comp2; are now detected and the recursive bit in the derived type's attr is set. gcc/fortran/ChangeLog: PR fortran/116669 * class.cc (gfc_find_derived_vtab): Use attr to determine cyclic type dependendies. * expr.cc (gfc_has_default_initializer): Prevent endless recursion by storing already visited derived types. * resolve.cc (resolve_cyclic_derived_type): Determine if a type is used in its hierarchy in a cyclic way. (resolve_fl_derived0): Call resolve_cyclic_derived_type. (resolve_fl_derived): Ensure vtab is generated when cyclic derived types have allocatable components. * trans-array.cc (structure_alloc_comps): Prevent endless loop for derived type cycles. * trans-expr.cc (gfc_get_ultimate_alloc_ptr_comps_caf_token): Off topic, just prevent memory leaks. gcc/testsuite/ChangeLog: * gfortran.dg/class_array_15.f03: Freeing more memory. * gfortran.dg/recursive_alloc_comp_6.f90: New test. --- gcc/fortran/trans-expr.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'gcc/fortran/trans-expr.cc') diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index bc24105..bef49d3 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -165,7 +165,10 @@ gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr) } if (last_caf_ref == NULL) - return NULL_TREE; + { + gfc_free_expr (caf_expr); + return NULL_TREE; + } tree comp = last_caf_ref->u.c.component->caf_token ? gfc_comp_caf_token (last_caf_ref->u.c.component) @@ -174,7 +177,10 @@ gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr) gfc_se se; bool comp_ref = !last_caf_ref->u.c.component->attr.dimension; if (comp == NULL_TREE && comp_ref) - return NULL_TREE; + { + gfc_free_expr (caf_expr); + return NULL_TREE; + } gfc_init_se (&se, outerse); gfc_free_ref_list (last_caf_ref->next); last_caf_ref->next = NULL; -- cgit v1.1