Skip to content

Commit f75b263

Browse files
authored
Merge branch 'main' into detect-compiler
2 parents e2008a0 + f9cca62 commit f75b263

File tree

8 files changed

+179
-58
lines changed

8 files changed

+179
-58
lines changed

example/smart_pointer.f90

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
module foo_m
2+
implicit none
3+
4+
private
5+
public :: foo_t
6+
7+
type foo_t
8+
end type
9+
10+
end module
11+
12+
module smart_pointer_m
13+
use reference_counter_m, only: ref_reference_t
14+
use foo_m, only : foo_t
15+
16+
implicit none
17+
private
18+
public :: smart_pointer_t
19+
20+
type, extends(ref_reference_t) :: smart_pointer_t
21+
type(foo_t), pointer :: ref => null()
22+
contains
23+
procedure :: free
24+
end type
25+
26+
interface smart_pointer_t
27+
28+
module function construct(foo) result(smart_pointer)
29+
implicit none
30+
type(foo_t), intent(in), pointer:: foo
31+
type(smart_pointer_t) :: smart_pointer
32+
end function
33+
34+
end interface
35+
36+
interface
37+
38+
module subroutine free(self)
39+
implicit none
40+
class(smart_pointer_t), intent(inout) :: self
41+
end subroutine
42+
43+
end interface
44+
45+
end module
46+
47+
submodule(smart_pointer_m) smart_pointer_s
48+
use assert_m, only : assert
49+
implicit none
50+
51+
contains
52+
53+
module procedure construct
54+
call assert(associated(foo), "construct_from_pointer: associated(foo)")
55+
smart_pointer%ref => foo
56+
call smart_pointer%start_ref_counter
57+
end procedure
58+
59+
module procedure free
60+
if (associated(self%ref)) then
61+
deallocate(self%ref)
62+
nullify(self%ref)
63+
print *,"free(): foo deallocated"
64+
end if
65+
end procedure
66+
67+
end submodule
68+
69+
program main
70+
use smart_pointer_m, only : smart_pointer_t
71+
use foo_m, only : foo_t
72+
implicit none
73+
74+
block
75+
76+
type(smart_pointer_t) ptr_1, ptr_2
77+
type(foo_t), pointer :: foo => null()
78+
79+
allocate(foo, source = foo_t())
80+
ptr_1 = smart_pointer_t(foo) ! 1st reference
81+
print *, ptr_1%reference_count()
82+
ptr_2 = ptr_1 ! 2nd reference
83+
print *, ptr_2%reference_count()
84+
call new_reference(ptr_2)
85+
print *, ptr_2%reference_count() ! 2 remaining references
86+
87+
end block ! ref_reference_counter frees the memory after the 2 remaining references go out of scope
88+
89+
print *,"All references gone"
90+
91+
contains
92+
93+
subroutine new_reference(obj)
94+
type(smart_pointer_t), intent(in) :: obj
95+
type(smart_pointer_t) local_ptr
96+
97+
local_ptr = obj ! 3rd reference
98+
print *, local_ptr%reference_count()
99+
end subroutine
100+
101+
end program

example/specification_expression_finalization.f90

Lines changed: 0 additions & 57 deletions
This file was deleted.

src/reference_counter/ref_counter_m.f90

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module ref_counter_m
1010
integer, pointer :: count_ => null()
1111
class(ref_resource_t), pointer :: object_ => null()
1212
contains
13+
procedure :: reference_count
1314
procedure, non_overridable :: grab
1415
procedure, non_overridable :: release
1516
procedure :: assign_ref_counter
@@ -29,6 +30,12 @@ module function construct(object) result(ref_counter)
2930

3031
interface
3132

33+
pure module function reference_count(self) result(counter)
34+
implicit none
35+
class(ref_counter_t), intent(in) :: self
36+
integer counter
37+
end function
38+
3239
module subroutine grab(self)
3340
implicit none
3441
class(ref_counter_t), intent(inout) :: self

src/reference_counter/ref_counter_s.f90

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
contains
66

7+
module procedure reference_count
8+
call assert(associated(self%count_),"ref_counter_t%grab: associated(self%count_)")
9+
counter = self%count_
10+
end procedure
11+
712
module procedure construct
813
allocate(ref_counter%count_, source=0)
914
allocate(ref_counter%object_, source=object)

src/reference_counter/ref_reference_m.f90

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@ module ref_reference_m
99
type, abstract, extends(ref_resource_t) :: ref_reference_t
1010
type(ref_counter_t) :: ref_counter
1111
contains
12+
procedure :: reference_count
1213
procedure, non_overridable :: release_handle
1314
procedure, non_overridable :: start_ref_counter
1415
end type
1516

1617
interface
1718

19+
pure module function reference_count(self) result(counter)
20+
implicit none
21+
class(ref_reference_t), intent(in) :: self
22+
integer counter
23+
end function
24+
1825
module subroutine release_handle(self)
1926
implicit none
2027
class(ref_reference_t), intent(inout) :: self

src/reference_counter/ref_reference_s.f90

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
contains
55

6+
module procedure reference_count
7+
counter = self%ref_counter%reference_count()
8+
end procedure
9+
610
module procedure release_handle
711
call self%ref_counter%release
812
end procedure

test/compiler_test.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module compiler_test
22
!! Test compiler conformance with each scenario in which the Fortran 2018
33
!! standard mandates type finalization.
4+
use for_use_in_spec_expr_m, only: finalizable_t, component, was_finalized
45
use veggies, only: result_t, test_item_t, describe, it, assert_equals, assert_that
56
use iso_fortran_env, only : compiler_version
67
implicit none
@@ -197,7 +198,7 @@ function check_rhs_function_reference() result(result_)
197198
end function
198199

199200
function check_specification_expression() result(result_)
200-
!! Test conformance with Fortran 2018 standard clause 7.5.6.3, paragraph 6:
201+
!! Test conformance with Fortran 2018 standard clause 7.5.6.3, paragraph 6:
201202
!! "specification expression function result"
202203
type(result_t) result_
203204
integer exit_status

test/for_use_in_spec_expr_m.f90

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module for_use_in_spec_expr_m
2+
!! This module supports the specification expression finalization
3+
!! test in compiler_test.f90, check_specification_expression
4+
implicit none
5+
6+
private
7+
public :: finalizable_t, component, was_finalized
8+
9+
type finalizable_t
10+
private
11+
integer, pointer :: component_ => null()
12+
contains
13+
final :: finalize
14+
end Type
15+
16+
interface finalizable_t
17+
module procedure construct
18+
end interface
19+
20+
logical :: was_finalized = .false.
21+
22+
interface
23+
pure subroutine lie()
24+
end subroutine
25+
end interface
26+
27+
contains
28+
29+
pure function construct(component) result(finalizable)
30+
integer, intent(in) :: component
31+
type(finalizable_t) finalizable
32+
allocate(finalizable%component_, source = component)
33+
end function
34+
35+
pure function component(self) result(self_component)
36+
type(finalizable_t), intent(in) :: self
37+
integer self_component
38+
if (.not. associated(self%component_)) error stop "component: unassociated component"
39+
self_component = self%component_
40+
end function
41+
42+
pure subroutine finalize(self)
43+
type(finalizable_t), intent(inout) :: self
44+
if (associated(self%component_)) deallocate(self%component_)
45+
call lie()
46+
end subroutine
47+
48+
end module
49+
50+
subroutine lie()
51+
use for_use_in_spec_expr_m, only: was_finalized
52+
was_finalized = .true.
53+
end subroutine

0 commit comments

Comments
 (0)