https://gcc.gnu.org/g:d5fd0f86b754194eabb34061a2845ede6e3f213c

commit r17-5269-gd5fd0f86b754194eabb34061a2845ede6e3f213c
Author: Jerry DeLisle <[email protected]>
Date:   Fri Oct 16 11:27:34 2026 -0700

    fortran: Fix ICE in finalizer of nested derived type array components
    
    The finalization wrapper guards the deallocation of each allocatable
    component with ASSOCIATED applied to the path of its parent.  For a
    derived type array component nested inside an array component of lower
    rank, that path holds two array sections and its rank does not match
    the outer section's, so converting it caused an ICE in
    gfc_get_descriptor_field.  The components on the path are neither
    pointers nor allocatable, so the patch tests the base pointer instead.
    
    gcc/fortran/ChangeLog:
    
            * class.cc (finalize_component): Apply ASSOCIATED to the base
            pointer of EXPR rather than to EXPR.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/finalize_63.f90: New test.

Diff:
---
 gcc/fortran/class.cc                      |  5 ++++-
 gcc/testsuite/gfortran.dg/finalize_63.f90 | 33 +++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 18cff8f47a18..faca0b877d0c 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -1130,7 +1130,10 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, 
gfc_component *comp,
       cond->block->expr1->ts.kind = gfc_default_logical_kind;
       cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id 
(GFC_ISYM_ASSOCIATED);
       cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
-      cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
+      /* EXPR only adds nonpointer, nonallocatable components to its base
+        pointer, so testing the base suffices.  */
+      cond->block->expr1->value.function.actual->expr
+       = gfc_lval_expr_from_sym (expr->symtree->n.sym);
       cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist 
();
       cond->block->next = dealloc;
 
diff --git a/gcc/testsuite/gfortran.dg/finalize_63.f90 
b/gcc/testsuite/gfortran.dg/finalize_63.f90
new file mode 100644
index 000000000000..8e7ac8531fbc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_63.f90
@@ -0,0 +1,33 @@
+! { dg-do compile }
+
+! The finalization wrapper of a type with a derived type array component
+! nested inside an array component of lower rank caused an ICE in
+! gfc_get_descriptor_field.
+
+module m
+  type leaf
+    real, allocatable :: value
+  end type
+  type item
+    type(leaf), allocatable :: children(:)
+  end type
+  type mid
+    integer :: k
+    type(item) :: its(2,3)
+  end type
+  type container
+    type(mid) :: mids(3)
+  end type
+  type deep
+    integer :: k
+    type(leaf) :: leaves(2,2,2)
+  end type
+  type, extends(container) :: ext
+    type(deep) :: deeps(2,2)
+  end type
+contains
+  subroutine s (x)
+    class(container), allocatable :: x
+    deallocate (x)
+  end subroutine
+end module

Reply via email to