Skip to content

Commit 26d2283

Browse files
Merge pull request #490 from jacobwilliams/489-clone-leak-fix
489 clone leak fix
2 parents 06d0c67 + 8ff8876 commit 26d2283

File tree

2 files changed

+116
-20
lines changed

2 files changed

+116
-20
lines changed

Diff for: src/json_value_module.F90

+13-20
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ end subroutine json_clone
13211321
!@note If new data is added to the [[json_value]] type,
13221322
! then this would need to be updated.
13231323

1324-
recursive subroutine json_value_clone_func(from,to,parent,previous,next,children,tail)
1324+
recursive subroutine json_value_clone_func(from,to,parent,previous,tail)
13251325

13261326
implicit none
13271327

@@ -1330,8 +1330,6 @@ recursive subroutine json_value_clone_func(from,to,parent,previous,next,children
13301330
!! must not already be associated)
13311331
type(json_value),pointer,optional :: parent !! to%parent
13321332
type(json_value),pointer,optional :: previous !! to%previous
1333-
type(json_value),pointer,optional :: next !! to%next
1334-
type(json_value),pointer,optional :: children !! to%children
13351333
logical,optional :: tail !! if "to" is the tail of
13361334
!! its parent's children
13371335

@@ -1352,33 +1350,28 @@ recursive subroutine json_value_clone_func(from,to,parent,previous,next,children
13521350
to%var_type = from%var_type
13531351
to%n_children = from%n_children
13541352

1355-
!allocate and associate the pointers as necessary:
1356-
1357-
if (present(parent)) to%parent => parent
1358-
if (present(previous)) to%previous => previous
1359-
if (present(next)) to%next => next
1360-
if (present(children)) to%children => children
1353+
! allocate and associate the pointers as necessary:
1354+
if (present(parent)) to%parent => parent
1355+
if (present(previous)) to%previous => previous
13611356
if (present(tail)) then
13621357
if (tail .and. associated(to%parent)) to%parent%tail => to
13631358
end if
13641359

13651360
if (associated(from%next) .and. associated(to%parent)) then
13661361
! we only clone the next entry in an array
13671362
! if the parent has also been cloned
1368-
allocate(to%next)
1369-
call json_value_clone_func(from%next,&
1370-
to%next,&
1371-
previous=to,&
1372-
parent=to%parent,&
1373-
tail=(.not. associated(from%next%next)))
1363+
call json_value_clone_func(from = from%next,&
1364+
to = to%next,&
1365+
previous = to,&
1366+
parent = to%parent,&
1367+
tail = (.not. associated(from%next%next)))
13741368
end if
13751369

13761370
if (associated(from%children)) then
1377-
allocate(to%children)
1378-
call json_value_clone_func(from%children,&
1379-
to%children,&
1380-
parent=to,&
1381-
tail=(.not. associated(from%children%next)))
1371+
call json_value_clone_func(from = from%children,&
1372+
to = to%children,&
1373+
parent = to,&
1374+
tail = (.not. associated(from%children%next)))
13821375
end if
13831376

13841377
end if

Diff for: src/tests/jf_test_48.F90

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
!*****************************************************************************************
2+
!>
3+
! Module for the 48th unit test.
4+
5+
module jf_test_48_mod
6+
7+
use json_module, wp => json_RK, IK => json_IK, LK => json_LK
8+
use, intrinsic :: iso_fortran_env , only: error_unit, output_unit
9+
10+
implicit none
11+
12+
private
13+
public :: test_48
14+
15+
character(len=*),parameter :: filename = '../files/inputs/big.json' !! large file to open
16+
17+
contains
18+
19+
subroutine test_48(error_cnt)
20+
21+
!! Clone test
22+
23+
implicit none
24+
25+
integer,intent(out) :: error_cnt
26+
27+
type(json_value),pointer :: p, p_clone
28+
type(json_core) :: json !! factory for manipulating `json_value` pointers
29+
30+
write(error_unit,'(A)') ''
31+
write(error_unit,'(A)') '================================='
32+
write(error_unit,'(A)') ' EXAMPLE 48'
33+
write(error_unit,'(A)') '================================='
34+
write(error_unit,'(A)') ''
35+
36+
error_cnt = 0
37+
call json%initialize()
38+
if (json%failed()) then
39+
call json%print_error_message(error_unit)
40+
error_cnt = error_cnt + 1
41+
end if
42+
43+
write(error_unit,'(A)') 'open file'
44+
call json%load(filename, p)
45+
if (json%failed()) then
46+
call json%print_error_message(error_unit)
47+
error_cnt = error_cnt + 1
48+
end if
49+
50+
!test the deep copy routine:
51+
write(error_unit,'(A)') 'json_clone test'
52+
call json%clone(p,p_clone)
53+
if (json%failed()) then
54+
call json%print_error_message(error_unit)
55+
error_cnt = error_cnt + 1
56+
end if
57+
58+
call json%destroy(p)
59+
if (json%failed()) then
60+
call json%print_error_message(error_unit)
61+
error_cnt = error_cnt + 1
62+
end if
63+
64+
call json%destroy(p_clone)
65+
if (json%failed()) then
66+
call json%print_error_message(error_unit)
67+
error_cnt = error_cnt + 1
68+
end if
69+
70+
if (error_cnt==0) then
71+
write(error_unit,'(A)') 'Success'
72+
else
73+
write(error_unit,'(A)') 'Failed'
74+
end if
75+
76+
write(error_unit,'(A)') ''
77+
78+
end subroutine test_48
79+
80+
end module jf_test_48_mod
81+
!*****************************************************************************************
82+
83+
!*****************************************************************************************
84+
#ifndef INTEGRATED_TESTS
85+
program jf_test_48
86+
87+
!! clone test
88+
89+
use jf_test_48_mod , only: test_48
90+
implicit none
91+
integer :: n_errors
92+
integer :: i !! counter
93+
94+
integer,parameter :: n_repeat = 1 !! number of times to repeat the test
95+
96+
do i = 1, n_repeat
97+
call test_48(n_errors)
98+
if (n_errors /= 0) stop 1
99+
end do
100+
101+
end program jf_test_48
102+
#endif
103+
!*****************************************************************************************

0 commit comments

Comments
 (0)