The attached patch fixes this. Regression tested on x86_64.
OK for mainline and then backport to 16?
Regards,
Jerry
---
fortran: fix ICE with procedure pointer declared in BLOCK
Procedure pointer declared inside a BLOCK construct in a program that has
contained procedures caused an ICE in convert_nonlocal_reference_op
(tree-nested.cc) because get_proc_pointer_decl set the proc pointer's
DECL_CONTEXT to NULL instead of the enclosing program function decl.
The root cause: the condition to call gfc_add_decl_to_function vs
gfc_add_decl_to_parent_function checked whether proc_name->backend_decl
matched current_function_decl. For a BLOCK namespace the proc_name has
FL_LABEL flavor and its backend_decl is never set, so the condition failed
and gfc_add_decl_to_parent_function was called. That function sets
DECL_CONTEXT to DECL_CONTEXT(current_function_decl), which is NULL for a
top-level program. The tree-nested pass then found no nesting level
matching target_context = NULL and crashed in the internal_error call
dereferencing the NULL target_context.
Fix: add the missing BLOCK namespace check (FL_LABEL flavor) so that
procedure pointers in BLOCK constructs are treated like regular variables
and added to the enclosing function via gfc_add_decl_to_function.
Assisted by: Claude Sonnet 4.6
PR fortran/105582
gcc/fortran/ChangeLog:
* trans-decl.cc (get_proc_pointer_decl): Add FL_LABEL check to
route BLOCK-construct procedure pointers to gfc_add_decl_to_function
rather than gfc_add_decl_to_parent_function.
gcc/testsuite/ChangeLog:
* gfortran.dg/block_proc_ptr_1.f90: New test.
---From 335403bd808e5f1f0431a627c1925a2c758b8fef Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Tue, 26 May 2026 19:21:52 -0700
Subject: [PATCH] fortran: fix ICE with procedure pointer declared in BLOCK
Procedure pointer declared inside a BLOCK construct in a program that has
contained procedures caused an ICE in convert_nonlocal_reference_op
(tree-nested.cc) because get_proc_pointer_decl set the proc pointer's
DECL_CONTEXT to NULL instead of the enclosing program function decl.
The root cause: the condition to call gfc_add_decl_to_function vs
gfc_add_decl_to_parent_function checked whether proc_name->backend_decl
matched current_function_decl. For a BLOCK namespace the proc_name has
FL_LABEL flavor and its backend_decl is never set, so the condition failed
and gfc_add_decl_to_parent_function was called. That function sets
DECL_CONTEXT to DECL_CONTEXT(current_function_decl), which is NULL for a
top-level program. The tree-nested pass then found no nesting level
matching target_context = NULL and crashed in the internal_error call
dereferencing the NULL target_context.
Fix: add the missing BLOCK namespace check (FL_LABEL flavor) so that
procedure pointers in BLOCK constructs are treated like regular variables
and added to the enclosing function via gfc_add_decl_to_function.
Assisted by: Claude Sonnet 4.6
PR fortran/105582
gcc/fortran/ChangeLog:
* trans-decl.cc (get_proc_pointer_decl): Add FL_LABEL check to
route BLOCK-construct procedure pointers to gfc_add_decl_to_function
rather than gfc_add_decl_to_parent_function.
gcc/testsuite/ChangeLog:
* gfortran.dg/block_proc_ptr_1.f90: New test.
---
gcc/fortran/trans-decl.cc | 7 ++-
.../gfortran.dg/block_proc_ptr_1.f90 | 43 +++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gfortran.dg/block_proc_ptr_1.f90
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index e6c9eaf1796..ee33616556c 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -2212,7 +2212,12 @@ get_proc_pointer_decl (gfc_symbol *sym)
if ((sym->ns->proc_name
&& sym->ns->proc_name->backend_decl == current_function_decl)
- || sym->attr.contained)
+ || sym->attr.contained
+ || (sym->ns->proc_name
+ && sym->ns->proc_name->attr.flavor == FL_LABEL))
+ /* The last condition handles BLOCK constructs: the proc_name has
+ FL_LABEL flavor and its backend_decl is not set, but the proc pointer
+ belongs to the enclosing function (current_function_decl). */
gfc_add_decl_to_function (decl);
else if (sym->ns->proc_name->attr.flavor != FL_MODULE)
gfc_add_decl_to_parent_function (decl);
diff --git a/gcc/testsuite/gfortran.dg/block_proc_ptr_1.f90 b/gcc/testsuite/gfortran.dg/block_proc_ptr_1.f90
new file mode 100644
index 00000000000..49cedfa7f2a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/block_proc_ptr_1.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+! PR fortran/105582
+! Procedure pointer declared inside a BLOCK construct in a program that has
+! contained procedures used to cause an ICE in convert_nonlocal_reference_op
+! (tree-nested.cc) because get_proc_pointer_decl erroneously called
+! gfc_add_decl_to_parent_function instead of gfc_add_decl_to_function,
+! leaving the decl with DECL_CONTEXT set to NULL instead of the enclosing
+! program's function_decl.
+
+module iface_m
+ implicit none
+ abstract interface
+ pure function init_i(x) result(y)
+ double precision, intent(in) :: x(:)
+ double precision, allocatable :: y(:)
+ end function
+ end interface
+end module
+
+program test_block_proc_ptr
+ use iface_m, only : init_i
+ implicit none
+ integer :: n = 0
+
+ block
+ procedure(init_i), pointer :: p
+ double precision, allocatable :: vals(:)
+ p => linear
+ vals = p([1d0, 2d0, 3d0])
+ if (any(abs(vals - [1d0, 2d0, 3d0]) > 1d-10)) n = n + 1
+ end block
+
+ if (n /= 0) stop 1
+
+contains
+
+ pure function linear(x) result(y)
+ double precision, intent(in) :: x(:)
+ double precision, allocatable :: y(:)
+ y = x
+ end function
+
+end program
--
2.54.0