2 ! { dg-options "-std=f2008" }
4 ! Test finalization on intrinsic assignment (F2018 (7.5.6.3))
5 ! With -std=f2008, structure and array constructors are finalized.
6 ! See finalize_38.f90 for the result with -std=gnu.
7 ! Tests fix for PR64290 as well.
15 final
:: destructor1
, destructor2
18 type, extends(simple
) :: complicated
21 final
:: destructor3
, destructor4
24 integer :: check_scalar
25 integer :: check_array(4)
27 real :: check_rarray(4)
28 integer :: final_count
= 0
33 subroutine destructor1(self
)
34 type(simple
), intent(inout
) :: self
35 check_scalar
= self
%ind
37 final_count
= final_count
+ 1
38 end subroutine destructor1
40 subroutine destructor2(self
)
41 type(simple
), intent(inout
) :: self(:)
43 check_array(1:size(self
, 1)) = self
%ind
44 final_count
= final_count
+ 1
45 end subroutine destructor2
47 subroutine destructor3(self
)
48 type(complicated
), intent(inout
) :: self
49 check_real
= self
%rind
51 final_count
= final_count
+ 1
52 end subroutine destructor3
54 subroutine destructor4(self
)
55 type(complicated
), intent(inout
) :: self(:)
57 check_rarray(1:size(self
, 1)) = self
%rind
58 final_count
= final_count
+ 1
59 end subroutine destructor4
61 function constructor1(ind
) result(res
)
62 class(simple
), allocatable
:: res
63 integer, intent(in
) :: ind
64 allocate (res
, source
= simple (ind
))
65 end function constructor1
67 function constructor2(ind
, rind
) result(res
)
68 class(simple
), allocatable
:: res(:)
69 integer, intent(in
) :: ind(:)
70 real, intent(in
), optional
:: rind(:)
71 type(complicated
), allocatable
:: src(:)
74 if (present (rind
)) then
75 sz
= min (size (ind
, 1), size (rind
, 1))
76 src
= [(complicated (ind(i
), rind(i
)), i
= 1, sz
)] ! { dg-warning "has been finalized" }
77 allocate (res
, source
= src
)
80 allocate (res
, source
= [(simple (ind(i
)), i
= 1, sz
)])
82 end function constructor2
84 subroutine test (cnt
, scalar
, array
, off
, rind
, rarray
)
89 real, optional
:: rind
90 real, optional
:: rarray(:)
91 if (final_count
.ne
. cnt
) then
92 print *, 1 + off
, final_count
, '(', cnt
, ')'
95 if (check_scalar
.ne
. scalar
) then
96 print *, 2 + off
, check_scalar
, '(', scalar
, ')'
99 if (any (check_array(1:size (array
, 1)) .ne
. array
)) then
100 print *, 3 + off
, check_array(1:size (array
, 1)) , '(', array
, ')'
103 if (present (rind
)) then
104 if (check_real
.ne
. rind
) then
105 print *, 4 + off
, check_real
,'(', rind
, ')'
109 if (present (rarray
)) then
110 if (any (check_rarray(1:size (rarray
, 1)) .ne
. rarray
)) then
111 print *, 5 + off
, check_rarray(1:size (rarray
, 1)), '(', rarray
, ')'
123 type(simple
), allocatable
:: MyType
, MyType2
124 type(simple
), allocatable
:: MyTypeArray(:)
125 type(simple
) :: ThyType
= simple(21), ThyType2
= simple(22)
126 class(simple
), allocatable
:: MyClass
127 class(simple
), allocatable
:: MyClassArray(:)
129 ! ************************
130 ! Derived type assignments
131 ! ************************
133 ! The original PR - no finalization of 'var' before (re)allocation
134 ! because it is deallocated on scope entry (para 1 of F2018 7.5.6.3.)
136 call test(0, 0, [0,0], 0)
138 if (.not
. allocated(MyType
)) allocate(MyType
)
143 ! This should result in a final call with self = simple(1) (para 1 of F2018 7.5.6.3.).
145 call test(1, 1, [0,0], 10)
147 allocate(MyTypeArray(2))
148 MyTypeArray
%ind
= [42, 43]
149 ! This should result in a final call with self = [simple(42),simple(43)],
150 ! followed by the finalization of the array constructor = self = [simple(21),simple(22)].
151 MyTypeArray
= [ThyType
, ThyType2
] ! { dg-warning "has been finalized" }
152 call test(2, 0, [21,22], 20)
154 ! This should result in a final call 'var' = initialization = simple(22),
155 ! followed by one with for the structure constructor.
156 ThyType2
= simple(99) ! { dg-warning "has been finalized" }
157 call test(2, 99, [0,0], 30)
159 ! This should result in a final call for 'var' with self = simple(21).
161 call test(1, 21, [0,0], 40)
163 ! This should result in two final calls; the last is for Mytype2 = simple(2).
164 deallocate (MyType
, MyType2
)
165 call test(2, 2, [0,0], 50)
167 ! This should result in one final call; MyTypeArray = [simple(21),simple(22)].
168 deallocate (MyTypeArray
)
169 call test(1, 0, [21,22], 60)
171 ! The lhs is finalized before assignment.
172 ! The function result is finalized after the assignment.
173 allocate (MyType
, source
= simple (11))
174 MyType
= constructor1 (99)
175 call test(2, 99, [0,0], 70)
183 ! This should result in a final call for MyClass, which is simple(3) and then
184 ! the structure constructor with value simple(4)).
185 allocate (MyClass
, source
= simple (3))
186 MyClass
= simple (4) ! { dg-warning "has been finalized" }
187 call test(2, 4, [0,0], 100)
189 ! This should result in a final call with the assigned value of simple(4).
191 call test(1, 4, [0,0], 110)
194 allocate (MyClassArray
, source
= [simple (5), simple (6)])
195 ! Make sure that there is no final call since MyClassArray is not allocated.
196 call test(0, 4, [0,0], 120)
198 MyClassArray
= [simple (7), simple (8)] ! { dg-warning "has been finalized" }
199 ! The first final call should finalize MyClassArray and the second should return
200 ! the value of the array constructor.
201 call test(2, 0, [7,8], 130)
203 ! This should result in a final call with the assigned value.
204 deallocate (MyClassArray
)
205 call test(1, 0, [7,8], 140)
207 ! This should produce no final calls since MyClassArray was deallocated.
208 allocate (MyClassArray
, source
= [complicated(1, 2.0),complicated(3, 4.0)])
210 ! This should produce calls to destructor4 then destructor2.
211 deallocate (MyClassArray
)
213 ! F2018 7.5.6.3: "If the entity is of extended type and the parent type is
214 ! finalizable, the parent component is finalized.
215 call test(2, 0, [1, 3], 150, rarray
= [2.0, 4.0])
217 ! This produces 2 final calls in turn for 'src' as it goes out of scope, for
218 ! MyClassArray before it is assigned to and the result of 'constructor2' after
219 ! the assignment, for which the result should be should be [10,20] & [10.0,20.0].
220 MyClassArray
= constructor2 ([10,20], [10.0,20.0])
221 call test(6, 0, [10,20], 160, rarray
= [10.0,20.0])
223 ! This produces two final calls with the contents of 'MyClassArray. and its
225 deallocate (MyClassArray
)
226 call test(2, 0, [10, 20], 170, rarray
= [10.0,20.0])
228 ! Clean up for valgrind testing
229 if (allocated (MyType
)) deallocate (MyType
)
230 if (allocated (MyType2
)) deallocate (MyType2
)
231 if (allocated (MyTypeArray
)) deallocate (MyTypeArray
)
232 if (allocated (MyClass
)) deallocate (MyClass
)
233 if (allocated (MyClassArray
)) deallocate (MyClassArray
)
235 ! Error messages printed out by 'test'.
236 if (fails
.ne
. 0) then
237 Print *, fails
, " Errors"
240 end program test_final