aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Anlauf <anlauf@gmx.de>2024-07-18 21:15:48 +0200
committerHarald Anlauf <anlauf@gmx.de>2024-07-19 17:40:27 +0200
commitc93be1606ecf8e0f65b96b67aa023fb456ceb3a3 (patch)
tree23c89bde7507677e7668fa36fd0bd57b7bfe6d7d
parentb2f47a5c1d5204131660ea0372a08e692df8844e (diff)
downloadgcc-c93be1606ecf8e0f65b96b67aa023fb456ceb3a3.zip
gcc-c93be1606ecf8e0f65b96b67aa023fb456ceb3a3.tar.gz
gcc-c93be1606ecf8e0f65b96b67aa023fb456ceb3a3.tar.bz2
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.
-rw-r--r--gcc/fortran/trans-array.cc4
-rw-r--r--gcc/testsuite/gfortran.dg/string_array_constructor_4.f9059
2 files changed, 62 insertions, 1 deletions
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index dc3de6c..c93a5f1 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -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);
diff --git a/gcc/testsuite/gfortran.dg/string_array_constructor_4.f90 b/gcc/testsuite/gfortran.dg/string_array_constructor_4.f90
new file mode 100644
index 0000000..b5b81f0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/string_array_constructor_4.f90
@@ -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