Hello Mikael,

Thanks for taking a look at this. I have incorporated your suggestion
in the attached, revamped patch.

Slightly more substantial modification has resulted for a review by
Claude, which pointed out that co-dimension variables were still
giving double free signals and already deallocated variables,
deallocated again with stat =, were segaulting. These defects are
fixed.

The patch passes regression testing on FC44/x86_64. OK for mainline?

Cheers

Paul

On Sun, 11 Oct 2026 at 11:43, Mikael Morin <[email protected]> wrote:
>
> Le 08/10/2026 à 14:32, Paul Richard Thomas a écrit :
> > bug4-dealloc-scope-exit.f90 fails in runtime with:
> >
> > Program received signal SIGSEGV: Segmentation fault - invalid memory 
> > reference.
> >
> > Backtrace for this error:
> > #0  0x7f2b83809803 in ???
> > #1  0x7f2b838083b5 in ???
> > #2  0x7f2b834dcfaf in ???
> > #3  0x40066f in n1
> > at /home/pault/prs/pdt_conformance/reducers/bug4-dealloc-scope-exit.f90:14
> > #4  0x4006c9 in main
> > at /home/pault/prs/pdt_conformance/reducers/bug4-dealloc-scope-exit.f90:14
> > Segmentation fault         (core dumped) ./a.out
> >
> > The patch is straightforward enough as not to need explanation.
> >
> > Passes regtesting on FC44/x86_64. OK for mainline.
> >
> > Cheers
> >
> > Paul
>
> > bug4.patch
> >
> > From b308d107d4ac32e348e2d728764e3910af9c3a92 Mon Sep 17 00:00:00 2001
> > From: Paul Thomas <[email protected]>
> > Date: Thu, 8 Oct 2026 09:58:52 +0100
> > Subject: [PATCH] Fortran: [meta-bug] [PDT] Parameterized derived type errors
> >  [PR82173]
> >
> > 2026-10-06  Paul Thomas  <[email protected]>
> >
> > gcc/fortran
> >       PR fortran/82173
> >       * trans-decl.cc (gfc_trans_deferred_vars): Small formatting
> >       adjustment followed by a guarding of the pdt component dealloc
> >       for allocatable variables.
> >
> > gcc/testsuite/
> >       PR fortran/82173
> >       * gfortran.dg/pdt_bug4.f90: New test.
> > ---
> >  gcc/fortran/trans-decl.cc              | 16 ++++++++++++++++
> >  gcc/testsuite/gfortran.dg/pdt_bug4.f90 | 14 ++++++++++++++
> >  2 files changed, 30 insertions(+)
> >  create mode 100644 gcc/testsuite/gfortran.dg/pdt_bug4.f90
> >
> > diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
> > index a614e71eced..0229cc7ab82 100644
> > --- a/gcc/fortran/trans-decl.cc
> > +++ b/gcc/fortran/trans-decl.cc
> > @@ -5179,6 +5179,22 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, 
> > gfc_wrapped_block * block)
> >             else
> >               tmp = NULL_TREE;
> >
> > +           if (sym->attr.allocatable && !sym->attr.result
> > +               && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)))
> > +             {
> > +               /* Only deallocate the PDT comonents if the variable has not
> > +                  been deallocated.  Arrays are guarded elsewhere.  */
> > +               tree null_cond, zero;
> > +               null_cond = sym->backend_decl;
> > +               zero = build_int_cst (TREE_TYPE (null_cond), 0);
> > +               null_cond = fold_build2_loc (input_location, NE_EXPR,
> > +                                            logical_type_node,
> > +                                            null_cond, zero);
> > +               tmp = build3_loc (input_location, COND_EXPR, void_type_node,
> > +                                 null_cond, tmp,
> > +                                 build_empty_stmt (input_location));
> > +             }
> > +
>  From the context, it seems that `tmp' can be NULL_TREE.  So please add
> a check excluding that case (unless there is something that already
> provides that guarantee).
> OK with that change.
>
> >             gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
> >           }
> >         else if (sym->attr.dummy)
>
From 078d9a3382280594ed869be3d974a4455a9a52f3 Mon Sep 17 00:00:00 2001
From: Paul Thomas <[email protected]>
Date: Mon, 12 Oct 2026 15:21:21 +0100
Subject: [PATCH] Fortran: [meta-bug] [PDT] Parameterized derived type errors
 [PR82173]

2026-10-12  Paul Thomas  <[email protected]>

gcc/fortran
	PR fortran/82173
	* trans-decl.cc (gfc_trans_deferred_vars): Small formatting
	adjustment followed by a guarding of the pdt component dealloc
	for allocatable scalar and codimensioned variables.
	* trans-stmt.cc (gfc_trans_deallocate): Likewise for all PDTs.

gcc/testsuite/
	PR fortran/82173
	* gfortran.dg/pdt_bug4.f90: New test.
---
 gcc/fortran/trans-decl.cc              | 19 +++++++++++++++++++
 gcc/fortran/trans-stmt.cc              | 15 +++++++++++++++
 gcc/testsuite/gfortran.dg/pdt_bug4.f90 | 23 +++++++++++++++++++++++
 3 files changed, 57 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/pdt_bug4.f90

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index a614e71eced..ab3ef3e9740 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5179,6 +5179,25 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
 	      else
 		tmp = NULL_TREE;
 
+	      if (tmp && sym->attr.allocatable && !sym->attr.result
+		  && (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl))
+		      || sym->attr.codimension))
+		{
+		  /* Only deallocate the PDT comonents if the variable has not
+		     been deallocated.  Arrays are guarded elsewhere.  */
+		  tree null_cond, zero;
+		  null_cond = sym->backend_decl;
+		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)))
+		    null_cond = gfc_conv_descriptor_data_get (null_cond);
+		  zero = build_int_cst (TREE_TYPE (null_cond), 0);
+		  null_cond = fold_build2_loc (input_location, NE_EXPR,
+					       logical_type_node,
+					       null_cond, zero);
+		  tmp = build3_loc (input_location, COND_EXPR, void_type_node,
+				    null_cond, tmp,
+				    build_empty_stmt (input_location));
+		}
+
 	      gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
 	    }
 	  else if (sym->attr.dummy)
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 19817180acd..6c3e9cdbb59 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -7968,6 +7968,21 @@ gfc_trans_deallocate (gfc_code *code)
 					 se.expr, pdt_rank);
 	}
 
+      if (tmp)
+	{
+	  tree null_cond, zero;
+	  null_cond = se.expr;
+	  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
+	    null_cond = gfc_conv_descriptor_data_get (null_cond);
+	  zero = build_int_cst (TREE_TYPE (null_cond), 0);
+	  null_cond = fold_build2_loc (input_location, NE_EXPR,
+				       logical_type_node,
+				       null_cond, zero);
+	  tmp = build3_loc (input_location, COND_EXPR, void_type_node,
+			    null_cond, tmp,
+	  build_empty_stmt (input_location));
+	}
+
       if (tmp)
 	gfc_add_expr_to_block (&se.pre, tmp);
 
diff --git a/gcc/testsuite/gfortran.dg/pdt_bug4.f90 b/gcc/testsuite/gfortran.dg/pdt_bug4.f90
new file mode 100644
index 00000000000..8295be0ec1b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_bug4.f90
@@ -0,0 +1,23 @@
+! { dg-do run }
+! { dg-options "-fcoarray=single" }
+! Used to seg fault on exit due to attempted double free of pdt_array components.
+! See attachment to PR82173 comment 10 - reproducers/bug4-dealloc-scope-exit.f90
+program n1
+  type :: t(n)
+    integer, len :: n = 1
+    integer :: v(n)
+  end type
+  type(t(4)), allocatable :: a[:]  ! Allocatable coarray
+  type(t(3)), allocatable :: b     ! NON-deferred len, allocatable
+  type(t(3)), allocatable :: c     !         ditto
+  integer :: istat
+  allocate (a[*])
+  allocate (b)
+  allocate (c)
+  a%v = 1
+  b%v = 2
+  c%v = 3
+  deallocate (a, b, c)
+  deallocate (c, stat = istat) ! Deallocating already allocated caused segfault.
+  print *, 'reached end', istat
+end program ! Segmentation fault - invalid memory reference
-- 
2.56.0

Reply via email to