[PATCH] Fix PR105582 ICE on procedure pointer assignment inside block
Jerry D <[email protected]>
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <[email protected]> |
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. ---
0001-fortran-fix-ICE-with-procedure-pointer-declared-in-B.patch
(text/x-patch, 4.1 KB)
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