File: allocate_with_source_24.f90

package info (click to toggle)
gcc-arm-none-eabi 15%3A12.2.rel1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 959,712 kB
  • sloc: cpp: 3,275,382; ansic: 2,061,766; ada: 840,956; f90: 208,513; makefile: 76,132; asm: 73,433; xml: 50,448; exp: 34,146; sh: 32,436; objc: 15,637; fortran: 14,012; python: 11,991; pascal: 6,787; awk: 4,779; perl: 3,054; yacc: 338; ml: 285; lex: 201; haskell: 122
file content (134 lines) | stat: -rw-r--r-- 3,526 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
! { dg-do run }
!
! Test that the temporary in a sourced-ALLOCATE is not freeed.
! PR fortran/79344
! Contributed by Juergen Reuter

module iso_varying_string
  implicit none

  type, public :: varying_string
     private
     character(LEN=1), dimension(:), allocatable :: chars
  end type varying_string

  interface assignment(=)
     module procedure op_assign_VS_CH
  end interface assignment(=)

  interface operator(/=)
     module procedure op_not_equal_VS_CA
  end interface operator(/=)

  interface len
     module procedure len_
  end interface len

  interface var_str
     module procedure var_str_
  end interface var_str

  public :: assignment(=)
  public :: operator(/=)
  public :: len

  private :: op_assign_VS_CH
  private :: op_not_equal_VS_CA
  private :: char_auto
  private :: len_
  private :: var_str_

contains

  elemental function len_ (string) result (length)
    type(varying_string), intent(in) :: string
    integer                          :: length
    if(ALLOCATED(string%chars)) then
       length = SIZE(string%chars)
    else
       length = 0
    endif
  end function len_

  elemental subroutine op_assign_VS_CH (var, exp)
    type(varying_string), intent(out) :: var
    character(LEN=*), intent(in)      :: exp
    var = var_str(exp)
  end subroutine op_assign_VS_CH

  pure function op_not_equal_VS_CA (var, exp) result(res)
    type(varying_string), intent(in) :: var
    character(LEN=*), intent(in)     :: exp
    logical :: res
    integer :: i
    res = .true.
    if (len(exp) /= size(var%chars)) return
    do i = 1, size(var%chars)
      if (var%chars(i) /= exp(i:i)) return
    end do
    res = .false.
  end function op_not_equal_VS_CA

  pure function char_auto (string) result (char_string)
    type(varying_string), intent(in) :: string
    character(LEN=len(string))       :: char_string
    integer                          :: i_char
    forall(i_char = 1:len(string))
       char_string(i_char:i_char) = string%chars(i_char)
    end forall
  end function char_auto

  elemental function var_str_ (char) result (string)
    character(LEN=*), intent(in) :: char
    type(varying_string)         :: string
    integer                      :: length
    integer                      :: i_char
    length = LEN(char)
    ALLOCATE(string%chars(length))
    forall(i_char = 1:length)
       string%chars(i_char) = char(i_char:i_char)
    end forall
  end function var_str_

end module iso_varying_string

!!!!!
 
program test_pr79344

  use iso_varying_string, string_t => varying_string

  implicit none

  type :: field_data_t
     type(string_t), dimension(:), allocatable :: name
  end type field_data_t

  type(field_data_t) :: model, model2
  allocate(model%name(2))
  model%name(1) = "foo"
  model%name(2) = "bar"
  call copy(model, model2)
contains

  subroutine copy(prt, prt_src)
    implicit none
    type(field_data_t), intent(inout) :: prt
    type(field_data_t), intent(in) :: prt_src
    integer :: i
    if (allocated (prt_src%name)) then
       if (prt_src%name(1) /= "foo") STOP 1
       if (prt_src%name(2) /= "bar") STOP 2

       if (allocated (prt%name))  deallocate (prt%name)
       allocate (prt%name (size (prt_src%name)), source = prt_src%name)
       ! The issue was, that prt_src was empty after sourced-allocate.
       if (prt_src%name(1) /= "foo") STOP 3
       if (prt_src%name(2) /= "bar") STOP 4
       if (prt%name(1) /= "foo") STOP 5
       if (prt%name(2) /= "bar") STOP 6
    end if
  end subroutine copy

end program test_pr79344