]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fortran: Fix ICE in ALLOCATE of sub-objects with recursive types
authorChristopher Albert <albert@tugraz.at>
Wed, 25 Feb 2026 08:41:27 +0000 (09:41 +0100)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Wed, 25 Feb 2026 20:24:24 +0000 (12:24 -0800)
The deep-copy wrapper generation for recursive allocatable array
components (PR121628) calls cgraph_node::add_new_function to register
the wrapper.  During PARSING state, add_new_function calls
finalize_function which triggers ggc_collect().  This garbage
collection frees locally-computed tree nodes (COMPONENT_REFs etc.)
in caller stack frames of structure_alloc_comps that are not yet
attached to any GC-rooted structure, causing a segfault when those
nodes are subsequently accessed.

Use finalize_function with no_collect=true to skip the collection.
The GC will run at a safe point later.

PR fortran/124235

gcc/fortran/ChangeLog:

* trans-array.cc (generate_element_copy_wrapper): Use
cgraph_node::finalize_function with no_collect=true instead
of cgraph_node::add_new_function to avoid garbage collection
while caller frames hold unrooted tree nodes.

gcc/testsuite/ChangeLog:

* gfortran.dg/pr124235.f90: New test.

Signed-off-by: Christopher Albert <albert@tugraz.at>
gcc/fortran/trans-array.cc
gcc/testsuite/gfortran.dg/pr124235.f90 [new file with mode: 0644]

index e7666416213895f6235568c72e49782c34e2c437..73bb90a4b601a34adf6ea420c4a7c3ca02107885 100644 (file)
@@ -10165,7 +10165,13 @@ generate_element_copy_wrapper (gfc_symbol *der_type, tree comp_type,
 
   pop_cfun ();
 
-  cgraph_node::add_new_function (fndecl, false);
+  /* Use finalize_function with no_collect=true to skip the ggc_collect
+     call that add_new_function would trigger.  This function is called
+     during tree lowering of structure_alloc_comps where caller stack
+     frames hold locally-computed tree nodes (COMPONENT_REFs etc.) that
+     are not yet attached to any GC root.  A collection at this point
+     would free those nodes and cause segfaults.  PR124235.  */
+  cgraph_node::finalize_function (fndecl, true);
 
   return build1 (ADDR_EXPR, get_copy_helper_pointer_type (), fndecl);
 }
diff --git a/gcc/testsuite/gfortran.dg/pr124235.f90 b/gcc/testsuite/gfortran.dg/pr124235.f90
new file mode 100644 (file)
index 0000000..30735ff
--- /dev/null
@@ -0,0 +1,46 @@
+! { dg-do compile }
+! PR fortran/124235 - ICE in ALLOCATE of sub-objects with recursive types
+!
+! Mutually-referencing derived types with a mix of allocatable and
+! fixed-size array components.  Allocating a sub-object of an
+! already-allocated component triggered a segfault during tree lowering
+! because garbage collection during deep-copy wrapper generation
+! invalidated locally-computed COMPONENT_REF tree nodes.
+
+program pr124235
+  implicit none
+
+  type :: alpha_t
+    integer, allocatable :: vals(:)
+    type(alpha_t), allocatable :: a_kids(:)
+    type(gamma_t), allocatable :: g_ref(:)
+    integer :: tag
+    type(beta_t), allocatable :: b_ref(:)
+  end type
+
+  type :: beta_t
+    integer, allocatable :: vals(:)
+    type(alpha_t) :: a_fixed(4)
+    type(beta_t), allocatable :: b_kids(:)
+    integer :: tag
+    type(gamma_t), allocatable :: g_ref(:)
+  end type
+
+  type :: gamma_t
+    integer, allocatable :: vals(:)
+    type(beta_t) :: b_fixed(4)
+    integer :: tag
+    type(gamma_t), allocatable :: g_kids(:)
+  end type
+
+  type :: container_t
+    type(gamma_t), allocatable :: items(:)
+    type(gamma_t), allocatable :: spares(:)
+  end type
+
+  type(container_t) :: box
+
+  allocate(box%items(6))
+  allocate(box%items(2)%g_kids(3))
+
+end program