| ! { dg-do run } |
| ! { dg-additional-options "-fdump-tree-original" } |
| ! |
| ! PR fortran/61831 |
| ! The deallocation of components of array constructor elements |
| ! used to have the side effect of also deallocating some other |
| ! variable's components from which they were copied. |
| |
| program main |
| implicit none |
| |
| integer, parameter :: n = 2 |
| |
| type :: string_t |
| character(LEN=1), dimension(:), allocatable :: chars |
| end type string_t |
| |
| type :: string_container_t |
| type(string_t) :: comp |
| end type string_container_t |
| |
| type :: string_array_container_t |
| type(string_t) :: comp(n) |
| end type string_array_container_t |
| |
| type(string_t) :: prt_in, tmp, tmpa(n) |
| type(string_container_t) :: tmpc, tmpca(n) |
| type(string_array_container_t) :: tmpac, tmpaca(n) |
| integer :: i, j, k |
| |
| do i=1,16 |
| |
| ! Test without intermediary function |
| prt_in = string_t(["A"]) |
| if (.not. allocated(prt_in%chars)) STOP 1 |
| if (any(prt_in%chars .ne. "A")) STOP 2 |
| deallocate (prt_in%chars) |
| |
| ! scalar elemental function |
| prt_in = string_t(["B"]) |
| if (.not. allocated(prt_in%chars)) STOP 3 |
| if (any(prt_in%chars .ne. "B")) STOP 4 |
| tmp = new_prt_spec (prt_in) |
| if (.not. allocated(prt_in%chars)) STOP 5 |
| if (any(prt_in%chars .ne. "B")) STOP 6 |
| deallocate (prt_in%chars) |
| deallocate (tmp%chars) |
| |
| ! array elemental function with array constructor |
| prt_in = string_t(["C"]) |
| if (.not. allocated(prt_in%chars)) STOP 7 |
| if (any(prt_in%chars .ne. "C")) STOP 8 |
| tmpa = new_prt_spec ([(prt_in, i=1,2)]) |
| if (.not. allocated(prt_in%chars)) STOP 9 |
| if (any(prt_in%chars .ne. "C")) STOP 10 |
| deallocate (prt_in%chars) |
| do j=1,n |
| deallocate (tmpa(j)%chars) |
| end do |
| |
| ! scalar elemental function with structure constructor |
| prt_in = string_t(["D"]) |
| if (.not. allocated(prt_in%chars)) STOP 11 |
| if (any(prt_in%chars .ne. "D")) STOP 12 |
| tmpc = new_prt_spec2 (string_container_t(prt_in)) |
| if (.not. allocated(prt_in%chars)) STOP 13 |
| if (any(prt_in%chars .ne. "D")) STOP 14 |
| deallocate (prt_in%chars) |
| deallocate(tmpc%comp%chars) |
| |
| ! array elemental function of an array constructor of structure constructors |
| prt_in = string_t(["E"]) |
| if (.not. allocated(prt_in%chars)) STOP 15 |
| if (any(prt_in%chars .ne. "E")) STOP 16 |
| tmpca = new_prt_spec2 ([ (string_container_t(prt_in), i=1,2) ]) |
| if (.not. allocated(prt_in%chars)) STOP 17 |
| if (any(prt_in%chars .ne. "E")) STOP 18 |
| deallocate (prt_in%chars) |
| do j=1,n |
| deallocate (tmpca(j)%comp%chars) |
| end do |
| |
| ! scalar elemental function with a structure constructor and a nested array constructor |
| prt_in = string_t(["F"]) |
| if (.not. allocated(prt_in%chars)) STOP 19 |
| if (any(prt_in%chars .ne. "F")) STOP 20 |
| tmpac = new_prt_spec3 (string_array_container_t([ (prt_in, i=1,2) ])) |
| if (.not. allocated(prt_in%chars)) STOP 21 |
| if (any(prt_in%chars .ne. "F")) STOP 22 |
| deallocate (prt_in%chars) |
| do j=1,n |
| deallocate (tmpac%comp(j)%chars) |
| end do |
| |
| ! array elemental function with an array constructor nested inside |
| ! a structure constructor nested inside an array constructor |
| prt_in = string_t(["G"]) |
| if (.not. allocated(prt_in%chars)) STOP 23 |
| if (any(prt_in%chars .ne. "G")) STOP 24 |
| tmpaca = new_prt_spec3 ([ (string_array_container_t([ (prt_in, i=1,2) ]), j=1,2) ]) |
| if (.not. allocated(prt_in%chars)) STOP 25 |
| if (any(prt_in%chars .ne. "G")) STOP 26 |
| deallocate (prt_in%chars) |
| do j=1,n |
| do k=1,n |
| deallocate (tmpaca(j)%comp(k)%chars) |
| end do |
| end do |
| |
| end do |
| |
| contains |
| |
| elemental function new_prt_spec (name) result (prt_spec) |
| type(string_t), intent(in) :: name |
| type(string_t) :: prt_spec |
| prt_spec = name |
| end function new_prt_spec |
| |
| elemental function new_prt_spec2 (name) result (prt_spec) |
| type(string_container_t), intent(in) :: name |
| type(string_container_t) :: prt_spec |
| prt_spec = name |
| end function new_prt_spec2 |
| |
| elemental function new_prt_spec3 (name) result (prt_spec) |
| type(string_array_container_t), intent(in) :: name |
| type(string_array_container_t) :: prt_spec |
| prt_spec = name |
| end function new_prt_spec3 |
| end program main |
| ! { dg-final { scan-tree-dump-times "__builtin_malloc" 15 "original" } } |
| ! { dg-final { scan-tree-dump-times "__builtin_free" 33 "original" } } |