Am 07.02.26 um 8:36 PM schrieb Harald Anlauf:
I therefore plan to split this part into a part 1 that is the submitted one minus the trans-array.cc part, and will continue to work on the remaining issues.
Part 1 is been pushed to mainline as (r16-7400-gdf7f52b3a4ca00. See also attached. Thanks, Harald
From df7f52b3a4ca00b64baf31c57c506fe3afe51c9f Mon Sep 17 00:00:00 2001 From: Harald Anlauf <[email protected]> Date: Sun, 8 Feb 2026 21:00:49 +0100 Subject: [PATCH] Fortran: fix string length for array constructors with type-spec [PR85547] PR fortran/85547 gcc/fortran/ChangeLog: * decl.cc (gfc_match_volatile): Fix frontend memleak. (gfc_match_asynchronous): Likewise. * dump-parse-tree.cc (show_expr): Show type-spec for character array constructor when given. * simplify.cc (gfc_simplify_len): Simplify LEN() when type-spec is provided for character array constructor. * trans-intrinsic.cc (gfc_conv_intrinsic_len): Likewise. gcc/testsuite/ChangeLog: * gfortran.dg/string_length_5.f90: New test. --- gcc/fortran/decl.cc | 4 +- gcc/fortran/dump-parse-tree.cc | 8 ++ gcc/fortran/simplify.cc | 15 ++++ gcc/fortran/trans-intrinsic.cc | 8 ++ gcc/testsuite/gfortran.dg/string_length_5.f90 | 88 +++++++++++++++++++ 5 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/string_length_5.f90 diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index e646d6b8f9a..2908007d75c 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -10405,7 +10405,7 @@ gfc_match_volatile (void) switch (m) { case MATCH_YES: - name = XCNEWVAR (char, strlen (sym->name) + 1); + name = XALLOCAVAR (char, strlen (sym->name) + 1); strcpy (name, sym->name); if (!check_function_name (name)) return MATCH_ERROR; @@ -10469,7 +10469,7 @@ gfc_match_asynchronous (void) switch (m) { case MATCH_YES: - name = XCNEWVAR (char, strlen (sym->name) + 1); + name = XALLOCAVAR (char, strlen (sym->name) + 1); strcpy (name, sym->name); if (!check_function_name (name)) return MATCH_ERROR; diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index b51414c13e2..028c946d2d9 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -545,6 +545,14 @@ show_expr (gfc_expr *p) case EXPR_ARRAY: fputs ("(/ ", dumpfile); + if (p->ts.type == BT_CHARACTER + && p->ts.u.cl + && p->ts.u.cl->length_from_typespec + && p->ts.u.cl->length) + { + show_typespec (&p->ts); + fputs (" :: ", dumpfile); + } show_constructor (p->value.constructor); fputs (" /)", dumpfile); diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc index a3af457b5de..c6291d7ea1d 100644 --- a/gcc/fortran/simplify.cc +++ b/gcc/fortran/simplify.cc @@ -5083,6 +5083,21 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind) } } } + else if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_CHARACTER + && e->ts.u.cl + && e->ts.u.cl->length_from_typespec + && e->ts.u.cl->length + && e->ts.u.cl->length->ts.type == BT_INTEGER) + { + gfc_typespec ts; + gfc_clear_ts (&ts); + ts.type = BT_INTEGER; + ts.kind = k; + result = gfc_copy_expr (e->ts.u.cl->length); + gfc_convert_type_warn (result, &ts, 2, 0); + return result; + } + return NULL; } diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index ec98f967200..39ed230e874 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -7647,6 +7647,14 @@ gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr) break; case EXPR_ARRAY: + /* If there is an explicit type-spec, use it. */ + if (arg->ts.u.cl->length && arg->ts.u.cl->length_from_typespec) + { + gfc_conv_string_length (arg->ts.u.cl, arg, &se->pre); + len = arg->ts.u.cl->backend_decl; + break; + } + /* Obtain the string length from the function used by trans-array.cc(gfc_trans_array_constructor). */ len = NULL_TREE; diff --git a/gcc/testsuite/gfortran.dg/string_length_5.f90 b/gcc/testsuite/gfortran.dg/string_length_5.f90 new file mode 100644 index 00000000000..12ae5a18466 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/string_length_5.f90 @@ -0,0 +1,88 @@ +! { dg-do run } +! PR fortran/85547 - string length for array constructors with type-spec +! +! Reported by Walter Spector + +program p + implicit none + integer, parameter :: k = 16 + integer :: m = k + integer, volatile :: n = k + character(10) :: path = 'xyz/' + character(8) :: path2 = 'abc/' + character(*), parameter :: s = 'ijk/' + if (k /= len ( [ character(k) :: path ] )) stop 1 + if (k /= len ( [ character(m) :: path ] )) stop 2 + if (k /= len ( [ character(n) :: path ] )) stop 3 + if (k /= len ( [ character(k) :: path ] ,kind=2)) stop 4 + if (k /= len ( [ character(m) :: path ] ,kind=2)) stop 5 + if (k /= len ( [ character(n) :: path ] ,kind=2)) stop 6 + + if (k /= len ( [ character(k) :: ] )) stop 7 + if (k /= len ( [ character(m) :: ] )) stop 8 + if (k /= len ( [ character(n) :: ] )) stop 9 + if (k /= len ( [ character(k) :: ] ,kind=2)) stop 10 + if (k /= len ( [ character(m) :: ] ,kind=2)) stop 11 + if (k /= len ( [ character(n) :: ] ,kind=2)) stop 12 + if (k /= len ( [ character(2*n/2) :: ] )) stop 13 + if (k /= len ( [ character(2*n/2) :: ] ,kind=2)) stop 14 + if (k /= len ( [ character((m+n)/2) ::] ,kind=2)) stop 15 + if (k /= len ( [ character((m+n)/2) ::] ,kind=2)) stop 16 + if (k /= len ([[ character(k) :: ]],kind=2)) stop 17 + if (k /= len ([[ character(m) :: ]],kind=2)) stop 18 + if (k /= len ([[ character(n) :: ]],kind=2)) stop 19 + if (k /= len ([[ character((m+n)/2) ::]],kind=2)) stop 20 + + if (k /= len ( [ character(k) :: path,path2 ] ,kind=2)) stop 21 + if (k /= len ( [ character(m) :: path,path2 ] ,kind=2)) stop 22 + if (k /= len ( [ character(n) :: path,path2 ] ,kind=2)) stop 23 + if (k /= len ( [ character((m+n)/2) :: path,path2 ] ,kind=2)) stop 24 + if (k /= len ([[ character(k) :: path,path2 ]],kind=2)) stop 25 + if (k /= len ([[ character(m) :: path,path2 ]],kind=2)) stop 26 + if (k /= len ([[ character(n) :: path,path2 ]],kind=2)) stop 27 + if (k /= len ([[ character((m+n)/2) :: path,path2 ]],kind=2)) stop 28 + + call sub () +contains + subroutine sub () +! call print_string (31, [ character(k) :: ] ) +! call print_string (32, [ character(m) :: ] ) +! call print_string (33, [ character(n) :: ] ) +! call print_string (34, [ character((m+n)/2) :: ] ) +! call print_string (35, [ character(k) :: path ] ) +! call print_string (36, [ character(m) :: path ] ) +! call print_string (37, [ character(n) :: path ] ) +! call print_string (38, [ character((m+n)/2) :: path ] ) +! call print_string (39, [ character(k) :: path,path2 ] ) +! call print_string (40, [ character(m) :: path,path2 ] ) +! call print_string (41, [ character(n) :: path,path2 ] ) +! call print_string (42, [ character((m+n)/2) :: path,path2 ] ) +! +! call print_string (51,[[ character(k) :: ]]) +! call print_string (52,[[ character(m) :: ]]) +! call print_string (53,[[ character(n) :: ]]) +! call print_string (54,[[ character((m+n)/2) :: ]]) +! call print_string (55,[[ character(k) :: path ]]) +! call print_string (56,[[ character(m) :: path ]]) +! call print_string (57,[[ character(n) :: path ]]) +! call print_string (58,[[ character((m+n)/2) :: path ]]) +! call print_string (59,[[ character(k) :: path,path2 ]]) +! call print_string (60,[[ character(m) :: path,path2 ]]) +! call print_string (61,[[ character(n) :: path,path2 ]]) +! call print_string (62,[[ character((m+n)/2) :: path,path2 ]]) + +! call print_string (70, [ character(k) :: ] ) + call print_string (71, [ character(k) :: s ] ) + call print_string (72, [ character(k) :: s,s ] ) + + end subroutine sub + + subroutine print_string (i, s) + integer, intent(in) :: i + character(*), intent(in) :: s(:) + if (len(s) /= k) then + print *, i, len(s), len(s)==k, size (s), s(:) + stop i + end if + end subroutine +end program -- 2.51.0
