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