Hello All,

The attached patch fixes PR127146.

I developed the fix but got myself into a bit of a mess with another
patch on the tree. This led pdt_71.f03 to regress. In the end, Claude
sorted out what was happening and produced the patch for this PR. I
left the assisted by line but the content of the patch is entirely
mine and Amir's.

Regression tested on FC44/x86_64 - OK for mainline and backporting to 16-branch?

(The reason for the latter is that I have been attempting to get the
handling of PDTs as up to date as possible on 16-branch.)

Regards

Paul
From 7c50c99221155d84f2740cf4564547448bff6ae5 Mon Sep 17 00:00:00 2001
From: Paul Thomas <[email protected]>
Date: Tue, 8 Sep 2026 09:15:04 +0100
Subject: [PATCH] Fix PDT constructor name corruption with extended types
 [PR127146]

When processing PDT constructors with inheritance, component names were being
unconditionally assigned to actual_arglist entries, even when those entries
already had correct names from the matched argument list. This caused name
corruption and duplicate component entries, leading to double-free errors.

The fix adds guards to only assign component names when the argument doesn't
already have a name. This preserves names from gfc_match_actual_arglist while
ensuring all arguments in the concatenated list are properly named.

Assisted-by: Claude Haiku 4.5 <[email protected]>
---
 gcc/fortran/primary.cc               |  6 ++++--
 gcc/testsuite/gfortran.dg/pdt_94.f03 | 32 ++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pdt_94.f03

diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index d167036b808..715dcb1188e 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -4225,7 +4225,8 @@ gfc_match_rvalue (gfc_expr **result)
 		{
 		  if (c->attr.pdt_kind || c->attr.pdt_len)
 		    continue;
-		  tmp->name = c->name;
+		  if (!tmp->name)
+		    tmp->name = c->name;
 		  tmp = tmp->next;
 		}
 
@@ -4251,7 +4252,8 @@ gfc_match_rvalue (gfc_expr **result)
 		  /* Can now add all the component names.  */
 		  for (c = pdt_sym->components; c && tmp; c = c->next)
 		    {
-		      tmp->name = c->name;
+		      if (!tmp->name)
+			tmp->name = c->name;
 		      tmp = tmp->next;
 		    }
 		}
diff --git a/gcc/testsuite/gfortran.dg/pdt_94.f03 b/gcc/testsuite/gfortran.dg/pdt_94.f03
new file mode 100644
index 00000000000..6aa9b6e5a50
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_94.f03
@@ -0,0 +1,32 @@
+! { dg-do run }
+! Test the fix for PR127146, where the structure constructors caused errors as
+! shown below.
+!
+! Contributed by Amir Shamoradi  <[email protected]>
+!
+module mod_pdt
+    implicit none
+    integer, parameter :: IK = kind(1)
+    integer, parameter :: IK8 = kind(1_8)
+    type :: pdt_parent(IKP)
+        integer, kind :: IKP
+        integer(IKP) :: ivalp
+    end type
+    type, extends(pdt_parent) :: pdt_child(IKC)
+        integer, kind :: IKC
+        integer(IKC) :: ivalc
+    end type
+end module mod_pdt
+
+    use mod_pdt
+    implicit none
+    type(pdt_child(IKP = IK, IKC = IK)) :: child1 = pdt_child(IKP = IK, IKC = IK)(ivalp = 1, ivalc = 2)
+    !!  double free or corruption (fasttop)
+
+    type(pdt_child(IKP = IK, IKC = IK8)) :: child2
+
+    child2 = pdt_child(IKP = IK, IKC = IK8)(ivalp = 3, ivalc = 4)
+    !!  Error: Component 'ivalc' is initialized twice in the structure constructor at (1)
+    if ((child1%ivalp /= 1) .or. (child1%ivalc /= 2)) stop 1
+    if ((child2%ivalp /= 3) .or. (child2%ivalc /= 4) .or. (kind (child2%ivalc) /= kind (1_8))) stop 2
+end
-- 
2.55.0

Reply via email to