From 5b264e77b54e211c7781d2c2e5dc324846a774a1 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Thu, 18 Jul 2024 21:15:48 +0200
Subject: [PATCH] Fortran: character array constructor with >= 4 constant
elements [PR103115]
gcc/fortran/ChangeLog:
PR fortran/103115
* trans-array.cc (gfc_trans_array_constructor_value): If the first
element of an array constructor is deferred-length character and
therefore does not have an element size known at compile time, do
not try to collect subsequent constant elements into a constructor
for optimization.
gcc/testsuite/ChangeLog:
PR fortran/103115
* gfortran.dg/string_array_constructor_4.f90: New test.
---
gcc/fortran/trans-array.cc | 4 +-
.../string_array_constructor_4.f90 | 59 +++++++++++++++++++
2 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gfortran.dg/string_array_constructor_4.f90
@@ -2147,7 +2147,9 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock,
p = gfc_constructor_next (p);
n++;
}
- if (n < 4)
+ /* Constructor with few constant elements, or element size not
+ known at compile time (e.g. deferred-length character). */
+ if (n < 4 || !INTEGER_CST_P (TYPE_SIZE_UNIT (type)))
{
/* Scalar values. */
gfc_init_se (&se, NULL);
new file mode 100644
@@ -0,0 +1,59 @@
+! { dg-do run }
+! PR fortran/103115 - character array constructor with >= 4 constant elements
+!
+! This used to ICE when the first element is deferred-length character
+! or could lead to wrong results.
+
+program pr103115
+ implicit none
+ integer :: i
+ character(*), parameter :: expect(*) = [ "1","2","3","4","5" ]
+ character(5) :: abc = "12345"
+ character(5), parameter :: def = "12345"
+ character(:), dimension(:), allocatable :: list
+ character(:), dimension(:), allocatable :: titles
+ titles = ["1"]
+ titles = [ titles&
+ ,"2"&
+ ,"3"&
+ ,"4"&
+ ,"5"& ! used to ICE
+ ]
+ if (len (titles) /= 1 .or. size (titles) /= 5) stop 1
+ if (any (titles /= expect)) stop 2
+ titles = ["1"]
+ titles = [ titles, (char(48+i),i=2,5) ]
+ if (len (titles) /= 1 .or. size (titles) /= 5) stop 3
+ if (any (titles /= expect)) stop 4
+ titles = ["1"]
+ titles = [ titles, ("2345"(i:i),i=1,4) ]
+ if (len (titles) /= 1 .or. size (titles) /= 5) stop 5
+ if (any (titles /= expect)) stop 6
+ titles = ["1"]
+ titles = [ titles, (def(i:i),i=2,5) ]
+ if (len (titles) /= 1 .or. size (titles) /= 5) stop 7
+ if (any (titles /= expect)) stop 8
+ list = [ (char(48+i),i=1,5) ]
+ titles = [ list(1), (char(48+i),i=2,5) ]
+ if (len (titles) /= 1 .or. size (titles) /= 5) stop 9
+ if (any (titles /= expect)) stop 10
+ titles = ["1"]
+ titles = [ titles, (abc(i:i),i=2,5) ]
+ if (len (titles) /= 1 .or. size (titles) /= 5) stop 11
+ if (any (titles /= expect)) stop 12
+
+ ! with typespec:
+ list = [ (char(48+i),i=1,5) ]
+ titles = [ character(2) :: list(1), (char(48+i),i=2,5) ]
+ if (len (titles) /= 2 .or. size (titles) /= 5) stop 13
+ if (any (titles /= expect)) stop 14
+ titles = ["1"]
+ titles = [ character(2) :: titles, (char(48+i),i=2,5) ]
+ if (len (titles) /= 2 .or. size (titles) /= 5) stop 15
+ if (any (titles /= expect)) stop 16
+ titles = ["1"]
+ titles = [ character(2) :: titles, (def(i:i),i=2,5) ]
+ if (len (titles) /= 2 .or. size (titles) /= 5) stop 17
+ if (any (titles /= expect)) stop 18
+ deallocate (titles, list)
+end
--
2.35.3