bug5-lower-bound-double-free.f90 crashes at runtime with:

double free or corruption (out)
Program received signal SIGABRT: Process abort signal.

The first chunk of the patch is the actual fix. It ensures that the
array offset is correctly calculated by multiplying the lbound by the
accumulated 'size'.

The second chunk tidies up an overlong line, which was noted in passing.

Passes regtesting on FC44/x86_64. OK for mainline.

Cheers

Paul
From 8174e732cd21d141d09b92bc86d8ee756b3c98df Mon Sep 17 00:00:00 2001
From: Paul Thomas <[email protected]>
Date: Tue, 6 Oct 2026 15:15:42 +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-array.cc (structure_alloc_comps): The contribution of
	the lbound must be multiplied by the accumulated size to obtain
	the offset.
	* trans-decl.cc (gfc_trans_deferred_vars): Add a minor format
	correction.

gcc/testsuite/
	PR fortran/82173
	* gfortran.dg/pdt_bug5.f90: New test.
---
 gcc/fortran/trans-array.cc             |  6 +++++-
 gcc/fortran/trans-decl.cc              |  3 ++-
 gcc/testsuite/gfortran.dg/pdt_bug5.f90 | 16 ++++++++++++++++
 3 files changed, 23 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pdt_bug5.f90

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index abc606dc627..80411f9df1a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -11209,10 +11209,14 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest,
 						  gfc_rank_cst[i],
 						  size);
 		  size = gfc_evaluate_now (size, &fnblock);
+		  tmp = fold_build2_loc (input_location,
+					 MULT_EXPR,
+					 gfc_array_index_type,
+					 lower, size);
 		  offset = fold_build2_loc (input_location,
 					    MINUS_EXPR,
 					    gfc_array_index_type,
-					    offset, size);
+					    offset, tmp);
 		  offset = gfc_evaluate_now (offset, &fnblock);
 		  tmp = fold_build2_loc (input_location, MINUS_EXPR,
 					 gfc_array_index_type,
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index ac79cbf97ea..f9f26a8be3a 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5153,7 +5153,8 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
 
       if (sym->ts.type == BT_DERIVED
 	  && sym->ts.u.derived
-	  && (sym->ts.u.derived->attr.pdt_type || sym->ts.u.derived->attr.pdt_comp))
+	  && (sym->ts.u.derived->attr.pdt_type
+	      || sym->ts.u.derived->attr.pdt_comp))
 	{
 	  is_pdt_type = true;
 	  gfc_init_block (&tmpblock);
diff --git a/gcc/testsuite/gfortran.dg/pdt_bug5.f90 b/gcc/testsuite/gfortran.dg/pdt_bug5.f90
new file mode 100644
index 00000000000..181aad100e8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_bug5.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! Heap corruption: parameterized array component with a non-default
+! lower bound was freed incorrectly at scope exit.
+! See attachment to PR82173 comment 10 - reproducers/bug5-lower-bound-double-free.f90
+program p
+  type :: t(n)
+    integer, len :: n = 1
+    integer :: a(0:n)
+    integer :: b(-n:0)
+  end type
+  type(t(3)) :: p1
+  p1%a = 1
+  p1%b = 2
+  if (sum (p1%a) /= 4) stop 1   ! correct value, then "double free or corruption (out)"
+  if (sum (p1%b) /= 8) stop 2   ! ditto
+end program
-- 
2.55.0

Reply via email to