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.

(cherry picked from commit c93be1606ecf8e0f65b96b67aa023fb456ceb3a3)
This commit is contained in:
Harald Anlauf 2024-07-18 21:15:48 +02:00
parent 187eec8a2f
commit ca0fa18add
2 changed files with 62 additions and 1 deletions

View file

@ -2137,7 +2137,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);

View file

@ -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