https://gcc.gnu.org/g:30907bc0f06bbd71e657311cfc43b9dab4e58e35

commit r17-4876-g30907bc0f06bbd71e657311cfc43b9dab4e58e35
Author: Jerry DeLisle <[email protected]>
Date:   Sun Oct 4 10:17:27 2026 -0700

    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.

Diff:
---
 gcc/fortran/st.cc                                  | 23 +++++---------
 .../coarray/team_allocated_coarrays_2.f90          | 35 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/gcc/fortran/st.cc b/gcc/fortran/st.cc
index b9c15b2d0f8e..90d7f8a7a5c6 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 000000000000..8040cd7e584e
--- /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

Reply via email to