See attached patch. A structure constructor that gives an explicit-length
allocatable character component an allocatable or deferred-length value
ICEs in fold_convert_loc. gfc_trans_subcomponent_assign falls through to
its final branch, which fold_converts the value, a pointer to the
string, to the component's character type. The patch copies the string
with gfc_trans_string_copy instead, which also truncates or blank-pads
it to the declared length.
The fix is the new BT_CHARACTER branch in gfc_trans_subcomponent_assign
in trans-expr.cc; the rest is the new test. The bug was found with the
Fujitsu compiler test suite; the test is new.
Regression tested on x86_64.
OK for mainline?
Regards,
Jerry
---
fortran: [PR125720] ICE assigning an allocatable character to an allocatable
component
In a structure constructor, copy a value into an explicit-length
allocatable character component with gfc_trans_string_copy instead of
a scalar fold_convert.
Assisted-by: Claude Opus 5.5
PR fortran/125720
gcc/fortran/ChangeLog:
* trans-expr.cc (gfc_trans_subcomponent_assign): Use
gfc_trans_string_copy for an explicit-length allocatable
character component.
gcc/testsuite/ChangeLog:
* gfortran.dg/structure_constructor_19.f90: New test.
>From 7bb0d7926c4b722159e6a69e79b42aab703fb269 Mon Sep 17 00:00:00 2001
From: Jerry DeLisle <[email protected]>
Date: Wed, 10 Jun 2026 08:36:59 -0700
Subject: [PATCH] fortran: [PR125720] ICE assigning an allocatable character to
an allocatable component
In a structure constructor, copy a value into an explicit-length
allocatable character component with gfc_trans_string_copy instead of
a scalar fold_convert.
Assisted-by: Claude Opus 5.5
PR fortran/125720
gcc/fortran/ChangeLog:
* trans-expr.cc (gfc_trans_subcomponent_assign): Use
gfc_trans_string_copy for an explicit-length allocatable
character component.
gcc/testsuite/ChangeLog:
* gfortran.dg/structure_constructor_19.f90: New test.
---
gcc/fortran/trans-expr.cc | 8 ++++
.../gfortran.dg/structure_constructor_19.f90 | 43 +++++++++++++++++++
2 files changed, 51 insertions(+)
create mode 100644 gcc/testsuite/gfortran.dg/structure_constructor_19.f90
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 265bc1c02dd..2d04fd79061 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -10597,6 +10597,14 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm,
se.string_length));
}
}
+ else if (cm->ts.type == BT_CHARACTER)
+ {
+ /* Copy into the explicit-length allocatable character component. */
+ gfc_conv_string_parameter (&se);
+ gfc_trans_string_copy (&block, cm->ts.u.cl->backend_decl, dest,
+ cm->ts.kind, se.string_length, se.expr,
+ expr->ts.kind);
+ }
else
{
gfc_add_modify (&block, tmp,
diff --git a/gcc/testsuite/gfortran.dg/structure_constructor_19.f90 b/gcc/testsuite/gfortran.dg/structure_constructor_19.f90
new file mode 100644
index 00000000000..50008895d9a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/structure_constructor_19.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+!
+! PR 125720
+!
+! A structure constructor that assigns an allocatable or deferred-length
+! character expression to an explicit-length allocatable character component
+! used to ICE in gfc_trans_subcomponent_assign (fold_convert_loc). Check that
+! it now compiles and copies with the correct truncation/padding.
+
+program p
+ type t
+ integer :: i
+ character(2), allocatable :: c
+ end type t
+ type(t) :: x
+
+ character(2), allocatable :: a
+ character(:), allocatable :: d
+
+ ! Allocatable, explicit-length source.
+ allocate (a)
+ a = "cd"
+ x = t (2, a)
+ if (x%i /= 2) stop 1
+ if (.not. allocated (x%c)) stop 2
+ if (len (x%c) /= 2) stop 3
+ if (x%c /= "cd") stop 4
+
+ ! Deferred-length source, exact length.
+ d = "ef"
+ x = t (3, d)
+ if (x%c /= "ef") stop 5
+
+ ! Deferred-length source, longer than the component -> truncated.
+ d = "ghij"
+ x = t (4, d)
+ if (x%c /= "gh") stop 6
+
+ ! Deferred-length source, shorter than the component -> blank padded.
+ d = "k"
+ x = t (5, d)
+ if (x%c /= "k ") stop 7
+end program p
--
2.56.0