See attached patch.
I plan to commit this shortly as it is fairly simple.
Regression tested on x86_64 and a new test case.
Thanks to Mikael for the discovery.
Regards,
Jerry
---
fortran: [PR127724] ICE inserting coarray deallocation before
END TEAM
Find the END TEAM statement by walking the team block's code list from
its head, and splice the guarded deallocation in front of it.
Assisted-by: Claude Opus 5.5
PR fortran/127724
gcc/fortran/ChangeLog:
* st.cc (deallocate_allocated_coarrays): Insert the guarded
deallocation before EXEC_END_TEAM, starting from the head of
the code list.
gcc/testsuite/ChangeLog:
* gfortran.dg/coarray/team_allocated_coarrays_2.f90: New test.
---
From 6db87883e20e7b985037b6fc33a1db81646eb70c Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Sun, 4 Oct 2026 10:17:27 -0700
Subject: [PATCH] fortran: [PR127724] ICE inserting coarray deallocation before
END TEAM
Find the END TEAM statement by walking the team block's code list from
its head, and splice the guarded deallocation in front of it.
Assisted-by: Claude Opus 5.5
PR fortran/127724
gcc/fortran/ChangeLog:
* st.cc (deallocate_allocated_coarrays): Insert the guarded
deallocation before EXEC_END_TEAM, starting from the head of
the code list.
gcc/testsuite/ChangeLog:
* gfortran.dg/coarray/team_allocated_coarrays_2.f90: New test.
---
gcc/fortran/st.cc | 23 ++++--------
.../coarray/team_allocated_coarrays_2.f90 | 35 +++++++++++++++++++
2 files changed, 42 insertions(+), 16 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/coarray/team_allocated_coarrays_2.f90
diff --git a/gcc/fortran/st.cc b/gcc/fortran/st.cc
index b9c15b2d0f8..90d7f8a7a5c 100644
--- a/gcc/fortran/st.cc
+++ b/gcc/fortran/st.cc
@@ -413,7 +413,7 @@ get_guarded_dealloc (gfc_namespace *ns, gfc_expr *expr)
void
deallocate_allocated_coarrays (vec<gfc_expr *> *team_allocs)
{
- gfc_code *dealloc, *last_stmt;
+ gfc_code *dealloc, **prev;
gfc_ref *ref, *aref = NULL;
int i;
@@ -447,21 +447,12 @@ deallocate_allocated_coarrays (vec<gfc_expr *> *team_allocs)
aref->u.ar.dimen_type[i] = DIMEN_THIS_IMAGE;
/* Insert the deallocation code before the END TEAM statement. */
- last_stmt = gfc_current_ns->code;
- while (last_stmt)
- {
- last_stmt = last_stmt->next;
- if (last_stmt->next->op == EXEC_END_TEAM || !last_stmt->next)
- {
- dealloc = get_guarded_dealloc (gfc_current_ns, e);
- if (dealloc)
- {
- dealloc->next = last_stmt->next;
- last_stmt->next = dealloc;
- break;
- }
- }
- }
+ for (prev = &gfc_current_ns->code; *prev; prev = &(*prev)->next)
+ if ((*prev)->op == EXEC_END_TEAM)
+ break;
+ dealloc = get_guarded_dealloc (gfc_current_ns, e);
+ dealloc->next = *prev;
+ *prev = dealloc;
gfc_free_expr (e);
e = NULL;
}
diff --git a/gcc/testsuite/gfortran.dg/coarray/team_allocated_coarrays_2.f90 b/gcc/testsuite/gfortran.dg/coarray/team_allocated_coarrays_2.f90
new file mode 100644
index 00000000000..8040cd7e584
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/team_allocated_coarrays_2.f90
@@ -0,0 +1,35 @@
+! { dg-do run }
+!
+! PR 127724 - ICE when a team block holds a single statement before
+! END TEAM.
+
+program prog
+ use, intrinsic :: iso_fortran_env, only: team_type
+ implicit none
+ type(team_type) :: team
+ integer, allocatable :: a[:], b(:)[:]
+ integer :: team_id
+
+ team_id = 1 + mod(this_image(), 2)
+ form team (team_id, team)
+
+ change team (team)
+ if (team_id == 1) then
+ allocate(a[*])
+ deallocate(a)
+ end if
+ end team
+ if (allocated (a)) stop 1
+
+ change team (team)
+ allocate(a[*], b(3)[*])
+ end team
+ if (allocated (a) .or. allocated (b)) stop 2
+
+ change team (team)
+ block
+ allocate(a[*])
+ end block
+ end team
+ if (allocated (a)) stop 3
+end program
--
2.55.0