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
