Hi all,

See attached PATCH

I found this bug while working on PR127941. It has been regression tested on 
x86_64.

It is simple if not obvious so I plan to commit later today. New test case 
included.

Regards,

Jerry

---

    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.


commit 59ef7dc6def76cbb3092ecb59b22a4dbf3b4ec71
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 --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 18cff8f47a1..faca0b877d0 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 00000000000..8e7ac8531fb
--- /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