From c32781e8f2b15dd471569807da4e8439b0b1115a Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Fri, 8 Apr 2022 15:11:05 -0400 Subject: [PATCH 01/24] Add comments to currently implemented tests --- test/compiler_test.f90 | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index deae098..0f733b2 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -15,11 +15,11 @@ module compiler_test type wrapper_t private type(object_t), allocatable :: object - end type + end type interface object_t module procedure construct - end interface + end interface integer :: finalizations = 0 integer, parameter :: avoid_unused_variable_warning = 1 @@ -29,14 +29,14 @@ module compiler_test function test_ref_reference() result(tests) type(test_item_t) :: tests - tests = & + tests = & describe( & "The compiler", & [ it("finalizes an intent(out) derived type dummy argument", check_intent_out_finalization) & ,it("finalizes an object upon explicit deallocation", check_finalize_on_deallocate) & ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & - ]) + ]) end function function construct() result(object) @@ -46,11 +46,12 @@ function construct() result(object) subroutine count_finalizations(self) type(object_t), intent(inout) :: self - finalizations = finalizations + 1 + finalizations = finalizations + 1 self%dummy = avoid_unused_variable_warning end subroutine function check_rhs_function_reference() result(result_) + !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) type(object_t), allocatable :: object type(result_t) result_ integer initial_tally, delta @@ -62,6 +63,7 @@ function check_rhs_function_reference() result(result_) end function function check_finalize_on_deallocate() result(result_) + !! Tests 7.5.6.3 case 2 (explicit deallocation on allocatable entity) type(object_t), allocatable :: object type(result_t) result_ integer initial_tally @@ -76,6 +78,7 @@ function check_finalize_on_deallocate() result(result_) end function function check_intent_out_finalization() result(result_) + !! Tests 7.5.6.3 case 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) type(result_t) result_ type(object_t) object integer initial_tally @@ -94,6 +97,7 @@ subroutine finalize_intent_out_arg(output) end function function check_allocatable_component_finalization() result(result_) + !! Tests 7.5.6.3 cases 2 (allocatable entity) & 7 type(wrapper_t), allocatable :: wrapper type(result_t) result_ integer initial_tally, delta @@ -115,5 +119,5 @@ subroutine finalize_intent_out_component(output) end subroutine end function - + end module compiler_test From 968a2be98b298995db9198e1cf86a97aefeee52b Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Fri, 8 Apr 2022 15:27:03 -0400 Subject: [PATCH 02/24] Add test for non-allocatable RHS variable --- test/compiler_test.f90 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 0f733b2..0e2a737 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -34,6 +34,7 @@ function test_ref_reference() result(tests) "The compiler", & [ it("finalizes an intent(out) derived type dummy argument", check_intent_out_finalization) & ,it("finalizes an object upon explicit deallocation", check_finalize_on_deallocate) & + ,it("finalizes a non-allocatable object on the RHS of an intrinsic assignment", check_rhs_object_assignment) & ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & ]) @@ -50,6 +51,19 @@ subroutine count_finalizations(self) self%dummy = avoid_unused_variable_warning end subroutine + function check_rhs_object_assignment() result(result_) + !! Tests 7.5.6.3 case 1 (intrinsic assignment with non-allocatable variable) + type(object_t) :: lhs, rhs + type(result_t) result_ + integer initial_tally, delta + + rhs%dummy = avoid_unused_variable_warning + initial_tally = finalizations + lhs = rhs ! finalizes rhs + delta = finalizations - initial_tally + result_ = assert_equals(1, delta) + end function + function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) type(object_t), allocatable :: object From cbe46345702669067390876a2ecafdf02345cfed Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 27 Apr 2022 18:28:13 -0400 Subject: [PATCH 03/24] Document test failures with GFortran 11.2 --- test/compiler_test.f90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 0e2a737..4d8c98f 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -53,6 +53,7 @@ subroutine count_finalizations(self) function check_rhs_object_assignment() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with non-allocatable variable) + !! Expected: 1; gfortran 11.2: 0 type(object_t) :: lhs, rhs type(result_t) result_ integer initial_tally, delta @@ -66,6 +67,7 @@ function check_rhs_object_assignment() result(result_) function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) + !! Expected: 1; gfortran 11.2: 0 type(object_t), allocatable :: object type(result_t) result_ integer initial_tally, delta From 5aa6c7e9fece472437ac05f29e8b027e28c547a1 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Thu, 28 Apr 2022 16:28:15 -0400 Subject: [PATCH 04/24] Add temporary PRINT statement in final subroutine --- test/compiler_test.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 4d8c98f..e3209c8 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -47,6 +47,7 @@ function construct() result(object) subroutine count_finalizations(self) type(object_t), intent(inout) :: self + print *, 'Finalizing...' finalizations = finalizations + 1 self%dummy = avoid_unused_variable_warning end subroutine From 95ee6acedb3fe6a9a3e5431aa447a9622fb914aa Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Thu, 28 Apr 2022 16:36:24 -0400 Subject: [PATCH 05/24] Standardize declarations --- test/compiler_test.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index e3209c8..a48ca15 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -57,7 +57,7 @@ function check_rhs_object_assignment() result(result_) !! Expected: 1; gfortran 11.2: 0 type(object_t) :: lhs, rhs type(result_t) result_ - integer initial_tally, delta + integer :: initial_tally, delta rhs%dummy = avoid_unused_variable_warning initial_tally = finalizations @@ -71,7 +71,7 @@ function check_rhs_function_reference() result(result_) !! Expected: 1; gfortran 11.2: 0 type(object_t), allocatable :: object type(result_t) result_ - integer initial_tally, delta + integer :: initial_tally, delta initial_tally = finalizations object = object_t() ! finalizes object_t result @@ -117,7 +117,7 @@ function check_allocatable_component_finalization() result(result_) !! Tests 7.5.6.3 cases 2 (allocatable entity) & 7 type(wrapper_t), allocatable :: wrapper type(result_t) result_ - integer initial_tally, delta + integer :: initial_tally, delta initial_tally = finalizations From 73a5a0a5348c068205082f0cdc6faee8778f1a5f Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Thu, 28 Apr 2022 16:37:54 -0400 Subject: [PATCH 06/24] Standardize more declarations --- test/compiler_test.f90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index a48ca15..12210c2 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -41,7 +41,7 @@ function test_ref_reference() result(tests) end function function construct() result(object) - type(object_t) object + type(object_t) :: object object%dummy = avoid_unused_variable_warning end function @@ -56,7 +56,7 @@ function check_rhs_object_assignment() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with non-allocatable variable) !! Expected: 1; gfortran 11.2: 0 type(object_t) :: lhs, rhs - type(result_t) result_ + type(result_t) :: result_ integer :: initial_tally, delta rhs%dummy = avoid_unused_variable_warning @@ -70,7 +70,7 @@ function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) !! Expected: 1; gfortran 11.2: 0 type(object_t), allocatable :: object - type(result_t) result_ + type(result_t) :: result_ integer :: initial_tally, delta initial_tally = finalizations @@ -82,8 +82,8 @@ function check_rhs_function_reference() result(result_) function check_finalize_on_deallocate() result(result_) !! Tests 7.5.6.3 case 2 (explicit deallocation on allocatable entity) type(object_t), allocatable :: object - type(result_t) result_ - integer initial_tally + type(result_t) :: result_ + integer :: initial_tally initial_tally = finalizations allocate(object) @@ -96,9 +96,9 @@ function check_finalize_on_deallocate() result(result_) function check_intent_out_finalization() result(result_) !! Tests 7.5.6.3 case 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) - type(result_t) result_ - type(object_t) object - integer initial_tally + type(result_t) :: result_ + type(object_t) :: object + integer :: initial_tally initial_tally = finalizations call finalize_intent_out_arg(object) @@ -116,7 +116,7 @@ subroutine finalize_intent_out_arg(output) function check_allocatable_component_finalization() result(result_) !! Tests 7.5.6.3 cases 2 (allocatable entity) & 7 type(wrapper_t), allocatable :: wrapper - type(result_t) result_ + type(result_t) :: result_ integer :: initial_tally, delta initial_tally = finalizations From 24e7224239f435984a324cb0a27279dbc68521e7 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Thu, 28 Apr 2022 16:39:11 -0400 Subject: [PATCH 07/24] Standardize the rest of the declarations --- test/compiler_test.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 12210c2..e6e31f3 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -7,14 +7,14 @@ module compiler_test type object_t private - integer dummy + integer :: dummy contains final :: count_finalizations end type type wrapper_t private - type(object_t), allocatable :: object + type(object_t), allocatable :: object end type interface object_t From 4083811923974ba45b65896393503f8aac5e8365 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Thu, 28 Apr 2022 17:23:13 -0400 Subject: [PATCH 08/24] Add block finalization test --- test/compiler_test.f90 | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index e6e31f3..52a4d6f 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -12,15 +12,15 @@ module compiler_test final :: count_finalizations end type + interface object_t + module procedure construct_object + end interface + type wrapper_t private type(object_t), allocatable :: object end type - interface object_t - module procedure construct - end interface - integer :: finalizations = 0 integer, parameter :: avoid_unused_variable_warning = 1 @@ -40,16 +40,18 @@ function test_ref_reference() result(tests) ]) end function - function construct() result(object) + function construct_object() result(object) + !! Constructor for object_t type(object_t) :: object - object%dummy = avoid_unused_variable_warning + object % dummy = avoid_unused_variable_warning end function subroutine count_finalizations(self) + !! Destructor for object_t type(object_t), intent(inout) :: self print *, 'Finalizing...' finalizations = finalizations + 1 - self%dummy = avoid_unused_variable_warning + self % dummy = avoid_unused_variable_warning end subroutine function check_rhs_object_assignment() result(result_) @@ -66,6 +68,20 @@ function check_rhs_object_assignment() result(result_) result_ = assert_equals(1, delta) end function + function check_block_finalization() result(result_) + !! Tests 7.5.6.3 case 4 + type(result_t) :: result_ + integer :: initial_tally, delta + + initial_tally = finalizations + block + type(object_t) :: object + object % dummy = avoid_unused_variable_warning + end block ! Finalizes object + delta = finalizations - initial_tally + result_ = assert_equals(1, delta) + end function + function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) !! Expected: 1; gfortran 11.2: 0 From 40ad71b12b266af0e82084a5d786d804fcc33a04 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Thu, 28 Apr 2022 17:26:57 -0400 Subject: [PATCH 09/24] Add hook in test list --- test/compiler_test.f90 | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 52a4d6f..b61284f 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -37,6 +37,7 @@ function test_ref_reference() result(tests) ,it("finalizes a non-allocatable object on the RHS of an intrinsic assignment", check_rhs_object_assignment) & ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & + ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & ]) end function @@ -68,20 +69,6 @@ function check_rhs_object_assignment() result(result_) result_ = assert_equals(1, delta) end function - function check_block_finalization() result(result_) - !! Tests 7.5.6.3 case 4 - type(result_t) :: result_ - integer :: initial_tally, delta - - initial_tally = finalizations - block - type(object_t) :: object - object % dummy = avoid_unused_variable_warning - end block ! Finalizes object - delta = finalizations - initial_tally - result_ = assert_equals(1, delta) - end function - function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) !! Expected: 1; gfortran 11.2: 0 @@ -110,6 +97,20 @@ function check_finalize_on_deallocate() result(result_) end associate end function + function check_block_finalization() result(result_) + !! Tests 7.5.6.3 case 4 + type(result_t) :: result_ + integer :: initial_tally, delta + + initial_tally = finalizations + block + type(object_t) :: object + object % dummy = avoid_unused_variable_warning + end block ! Finalizes object + delta = finalizations - initial_tally + result_ = assert_equals(1, delta) + end function + function check_intent_out_finalization() result(result_) !! Tests 7.5.6.3 case 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) type(result_t) :: result_ From 6763989c807f1ae04f631059e8a0ffc0a230f1de Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 17:14:07 -0400 Subject: [PATCH 10/24] Add test for finalization at end subroutine --- test/compiler_test.f90 | 55 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index b61284f..5b1c991 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -21,6 +21,17 @@ module compiler_test type(object_t), allocatable :: object end type + type elem_t + private + integer :: dummy + contains + final :: count_elemental_finalizations + end type + + interface elem_t + module procedure construct_elem + end interface elem_t + integer :: finalizations = 0 integer, parameter :: avoid_unused_variable_warning = 1 @@ -38,6 +49,7 @@ function test_ref_reference() result(tests) ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & + ,it("finalizes a non-pointer non-allocatable array object at the END statement", check_finalize_on_end) & ]) end function @@ -50,8 +62,24 @@ function construct_object() result(object) subroutine count_finalizations(self) !! Destructor for object_t type(object_t), intent(inout) :: self - print *, 'Finalizing...' + print *, 'Finalizing object...' + finalizations = finalizations + 1 + self % dummy = avoid_unused_variable_warning + end subroutine + + elemental function construct_elem() result(elem) + !! Constructor for elem_t + type(elem_t) :: elem + elem % dummy = avoid_unused_variable_warning + end function + + elemental subroutine count_elemental_finalizations(self) + !! Destructor for elem_t + type(elem_t), intent(out) :: self + print *, 'Finalizing element...' + !$omp atomic update finalizations = finalizations + 1 + !$omp end atomic self % dummy = avoid_unused_variable_warning end subroutine @@ -72,7 +100,7 @@ function check_rhs_object_assignment() result(result_) function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) !! Expected: 1; gfortran 11.2: 0 - type(object_t), allocatable :: object + type(object_t), allocatable :: object type(result_t) :: result_ integer :: initial_tally, delta @@ -84,7 +112,7 @@ function check_rhs_function_reference() result(result_) function check_finalize_on_deallocate() result(result_) !! Tests 7.5.6.3 case 2 (explicit deallocation on allocatable entity) - type(object_t), allocatable :: object + type(object_t), allocatable :: object type(result_t) :: result_ integer :: initial_tally @@ -97,6 +125,27 @@ function check_finalize_on_deallocate() result(result_) end associate end function + function check_finalize_on_end() result(result_) + !! Tests 7.5.6.3 case 3 + type(result_t) :: result_ + integer :: initial_tally + integer, parameter :: nelems = 2 + + initial_tally = finalizations + call finalize_on_end_subroutine() + associate(final_tally => finalizations - initial_tally) + result_ = assert_equals(nelems, final_tally) + end associate + + contains + + subroutine finalize_on_end_subroutine() + type(elem_t) :: array(nelems) + array(:) % dummy = avoid_unused_variable_warning + end subroutine + + end function + function check_block_finalization() result(result_) !! Tests 7.5.6.3 case 4 type(result_t) :: result_ From 7c5bbc85425326bb6d5babc6cf142bbdd5a0e549 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 17:15:28 -0400 Subject: [PATCH 11/24] Remove print statement --- test/compiler_test.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 5b1c991..7c4696b 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -76,7 +76,6 @@ elemental function construct_elem() result(elem) elemental subroutine count_elemental_finalizations(self) !! Destructor for elem_t type(elem_t), intent(out) :: self - print *, 'Finalizing element...' !$omp atomic update finalizations = finalizations + 1 !$omp end atomic From a65e45d95ca803a4a930435e090bb71cd04af2ce Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 17:16:14 -0400 Subject: [PATCH 12/24] Fix intent --- test/compiler_test.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 7c4696b..24c5326 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -75,7 +75,7 @@ elemental function construct_elem() result(elem) elemental subroutine count_elemental_finalizations(self) !! Destructor for elem_t - type(elem_t), intent(out) :: self + type(elem_t), intent(inout) :: self !$omp atomic update finalizations = finalizations + 1 !$omp end atomic From c5a33772df8e3fa4a63d331f7d9cbf7a777b52cf Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 17:54:39 -0400 Subject: [PATCH 13/24] Rework elemental final subroutine --- test/compiler_test.f90 | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 24c5326..8ebd669 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -34,6 +34,9 @@ module compiler_test integer :: finalizations = 0 integer, parameter :: avoid_unused_variable_warning = 1 + integer, parameter :: toggled_state = -1 + + integer, parameter :: nelems = 2 contains @@ -76,10 +79,8 @@ elemental function construct_elem() result(elem) elemental subroutine count_elemental_finalizations(self) !! Destructor for elem_t type(elem_t), intent(inout) :: self - !$omp atomic update - finalizations = finalizations + 1 - !$omp end atomic - self % dummy = avoid_unused_variable_warning + integer, intent(out) :: count + self % dummy = toggled_state end subroutine function check_rhs_object_assignment() result(result_) @@ -127,19 +128,22 @@ function check_finalize_on_deallocate() result(result_) function check_finalize_on_end() result(result_) !! Tests 7.5.6.3 case 3 type(result_t) :: result_ - integer :: initial_tally - integer, parameter :: nelems = 2 + type(elem_t) :: array(nelems) + logical :: finalized(nelems) + integer :: initial_tally, delta + intrinsic :: count initial_tally = finalizations + finalized(:) = .FALSE. call finalize_on_end_subroutine() - associate(final_tally => finalizations - initial_tally) - result_ = assert_equals(nelems, final_tally) - end associate + where (array%dummy == toggled_state) finalized = .TRUE. + delta = count(finalized) + result_ = assert_equals(nelems, delta) + finalizations = finalizations + delta contains subroutine finalize_on_end_subroutine() - type(elem_t) :: array(nelems) array(:) % dummy = avoid_unused_variable_warning end subroutine @@ -180,7 +184,7 @@ subroutine finalize_intent_out_arg(output) function check_allocatable_component_finalization() result(result_) !! Tests 7.5.6.3 cases 2 (allocatable entity) & 7 - type(wrapper_t), allocatable :: wrapper + type(wrapper_t), allocatable :: wrapper type(result_t) :: result_ integer :: initial_tally, delta From 76bf250df31f607ef2b264d77487d2cbe7878ff4 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 17:55:29 -0400 Subject: [PATCH 14/24] Remove extraneous statement --- test/compiler_test.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 8ebd669..b290ebc 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -79,7 +79,6 @@ elemental function construct_elem() result(elem) elemental subroutine count_elemental_finalizations(self) !! Destructor for elem_t type(elem_t), intent(inout) :: self - integer, intent(out) :: count self % dummy = toggled_state end subroutine From f495863c1ee211dbc39fa365f4274a34bbb7af50 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 18:13:11 -0400 Subject: [PATCH 15/24] Rework elemental final subroutine, again --- test/compiler_test.f90 | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index b290ebc..580e19c 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -80,6 +80,11 @@ elemental subroutine count_elemental_finalizations(self) !! Destructor for elem_t type(elem_t), intent(inout) :: self self % dummy = toggled_state + call increment_finalizations() + end subroutine + + subroutine increment_finalizations() + finalizations = finalizations + 1 end subroutine function check_rhs_object_assignment() result(result_) @@ -127,23 +132,20 @@ function check_finalize_on_deallocate() result(result_) function check_finalize_on_end() result(result_) !! Tests 7.5.6.3 case 3 type(result_t) :: result_ - type(elem_t) :: array(nelems) - logical :: finalized(nelems) - integer :: initial_tally, delta + integer :: initial_tally intrinsic :: count initial_tally = finalizations - finalized(:) = .FALSE. - call finalize_on_end_subroutine() - where (array%dummy == toggled_state) finalized = .TRUE. - delta = count(finalized) - result_ = assert_equals(nelems, delta) - finalizations = finalizations + delta + call finalize_on_end_subroutine() ! Finalizes local_array + associate(final_tally => finalizations - initial_tally) + result_ = assert_equals(nelems, final_tally) + end associate contains subroutine finalize_on_end_subroutine() - array(:) % dummy = avoid_unused_variable_warning + type(elem_t) :: local_array(nelems) + local_array % dummy = avoid_unused_variable_warning end subroutine end function From e38c9c321e935e8611b6086406c1fcd98516cc66 Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 18:18:12 -0400 Subject: [PATCH 16/24] Rework incrementer --- test/compiler_test.f90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 580e19c..070a9a5 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -80,11 +80,12 @@ elemental subroutine count_elemental_finalizations(self) !! Destructor for elem_t type(elem_t), intent(inout) :: self self % dummy = toggled_state - call increment_finalizations() + call increment(finalizations) end subroutine - subroutine increment_finalizations() - finalizations = finalizations + 1 + pure subroutine increment(counter) + integer, intent(inout) :: counter + counter = counter + 1 end subroutine function check_rhs_object_assignment() result(result_) From b63078f16cfefbc6c8271b20034f99310d90120d Mon Sep 17 00:00:00 2001 From: Wileam Phan Date: Wed, 4 May 2022 18:46:32 -0400 Subject: [PATCH 17/24] Remove elemental test, for now --- test/compiler_test.f90 | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 070a9a5..2643ccf 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -21,22 +21,8 @@ module compiler_test type(object_t), allocatable :: object end type - type elem_t - private - integer :: dummy - contains - final :: count_elemental_finalizations - end type - - interface elem_t - module procedure construct_elem - end interface elem_t - integer :: finalizations = 0 integer, parameter :: avoid_unused_variable_warning = 1 - integer, parameter :: toggled_state = -1 - - integer, parameter :: nelems = 2 contains @@ -70,24 +56,6 @@ subroutine count_finalizations(self) self % dummy = avoid_unused_variable_warning end subroutine - elemental function construct_elem() result(elem) - !! Constructor for elem_t - type(elem_t) :: elem - elem % dummy = avoid_unused_variable_warning - end function - - elemental subroutine count_elemental_finalizations(self) - !! Destructor for elem_t - type(elem_t), intent(inout) :: self - self % dummy = toggled_state - call increment(finalizations) - end subroutine - - pure subroutine increment(counter) - integer, intent(inout) :: counter - counter = counter + 1 - end subroutine - function check_rhs_object_assignment() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with non-allocatable variable) !! Expected: 1; gfortran 11.2: 0 @@ -137,16 +105,16 @@ function check_finalize_on_end() result(result_) intrinsic :: count initial_tally = finalizations - call finalize_on_end_subroutine() ! Finalizes local_array + call finalize_on_end_subroutine() ! Finalizes local_obj associate(final_tally => finalizations - initial_tally) - result_ = assert_equals(nelems, final_tally) + result_ = assert_equals(1, final_tally) end associate contains subroutine finalize_on_end_subroutine() - type(elem_t) :: local_array(nelems) - local_array % dummy = avoid_unused_variable_warning + type(object_t) :: local_obj + local_obj % dummy = avoid_unused_variable_warning end subroutine end function From a4f57f3dad1cf1efbc70bfe6bbbdc3d200feb997 Mon Sep 17 00:00:00 2001 From: "Wileam Y. Phan" <50928756+wyphan@users.noreply.github.com> Date: Wed, 4 May 2022 21:03:17 -0400 Subject: [PATCH 18/24] Remove unnecessary double colons --- test/compiler_test.f90 | 43 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 2643ccf..ae78318 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -7,7 +7,7 @@ module compiler_test type object_t private - integer :: dummy + integer dummy contains final :: count_finalizations end type @@ -27,7 +27,7 @@ module compiler_test contains function test_ref_reference() result(tests) - type(test_item_t) :: tests + type(test_item_t) tests tests = & describe( & @@ -44,7 +44,7 @@ function test_ref_reference() result(tests) function construct_object() result(object) !! Constructor for object_t - type(object_t) :: object + type(object_t) object object % dummy = avoid_unused_variable_warning end function @@ -59,9 +59,9 @@ subroutine count_finalizations(self) function check_rhs_object_assignment() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with non-allocatable variable) !! Expected: 1; gfortran 11.2: 0 - type(object_t) :: lhs, rhs - type(result_t) :: result_ - integer :: initial_tally, delta + type(object_t) lhs, rhs + type(result_t) result_ + integer initial_tally, delta rhs%dummy = avoid_unused_variable_warning initial_tally = finalizations @@ -74,8 +74,8 @@ function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) !! Expected: 1; gfortran 11.2: 0 type(object_t), allocatable :: object - type(result_t) :: result_ - integer :: initial_tally, delta + type(result_t) result_ + integer initial_tally, delta initial_tally = finalizations object = object_t() ! finalizes object_t result @@ -86,8 +86,8 @@ function check_rhs_function_reference() result(result_) function check_finalize_on_deallocate() result(result_) !! Tests 7.5.6.3 case 2 (explicit deallocation on allocatable entity) type(object_t), allocatable :: object - type(result_t) :: result_ - integer :: initial_tally + type(result_t) result_ + integer initial_tally initial_tally = finalizations allocate(object) @@ -100,9 +100,8 @@ function check_finalize_on_deallocate() result(result_) function check_finalize_on_end() result(result_) !! Tests 7.5.6.3 case 3 - type(result_t) :: result_ - integer :: initial_tally - intrinsic :: count + type(result_t) result_ + integer initial_tally initial_tally = finalizations call finalize_on_end_subroutine() ! Finalizes local_obj @@ -113,7 +112,7 @@ function check_finalize_on_end() result(result_) contains subroutine finalize_on_end_subroutine() - type(object_t) :: local_obj + type(object_t) local_obj local_obj % dummy = avoid_unused_variable_warning end subroutine @@ -121,12 +120,12 @@ subroutine finalize_on_end_subroutine() function check_block_finalization() result(result_) !! Tests 7.5.6.3 case 4 - type(result_t) :: result_ - integer :: initial_tally, delta + type(result_t) result_ + integer initial_tally, delta initial_tally = finalizations block - type(object_t) :: object + type(object_t) object object % dummy = avoid_unused_variable_warning end block ! Finalizes object delta = finalizations - initial_tally @@ -135,9 +134,9 @@ function check_block_finalization() result(result_) function check_intent_out_finalization() result(result_) !! Tests 7.5.6.3 case 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) - type(result_t) :: result_ - type(object_t) :: object - integer :: initial_tally + type(result_t) result_ + type(object_t) object + integer initial_tally initial_tally = finalizations call finalize_intent_out_arg(object) @@ -155,8 +154,8 @@ subroutine finalize_intent_out_arg(output) function check_allocatable_component_finalization() result(result_) !! Tests 7.5.6.3 cases 2 (allocatable entity) & 7 type(wrapper_t), allocatable :: wrapper - type(result_t) :: result_ - integer :: initial_tally, delta + type(result_t) result_ + integer initial_tally, delta initial_tally = finalizations From 90012ed6aa173be34fffcb5f483d7a59a99b265d Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Wed, 4 May 2022 18:04:21 -0700 Subject: [PATCH 19/24] rm temporary output --- test/compiler_test.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index ae78318..df783e2 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -51,7 +51,6 @@ function construct_object() result(object) subroutine count_finalizations(self) !! Destructor for object_t type(object_t), intent(inout) :: self - print *, 'Finalizing object...' finalizations = finalizations + 1 self % dummy = avoid_unused_variable_warning end subroutine From c8ae6fdbdfd9168e2b70ef80d3c737ca2add4fb4 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Wed, 4 May 2022 18:13:54 -0700 Subject: [PATCH 20/24] refac(compiler_test): clarify standard citations --- test/compiler_test.f90 | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index df783e2..6dfbe57 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -34,7 +34,7 @@ function test_ref_reference() result(tests) "The compiler", & [ it("finalizes an intent(out) derived type dummy argument", check_intent_out_finalization) & ,it("finalizes an object upon explicit deallocation", check_finalize_on_deallocate) & - ,it("finalizes a non-allocatable object on the RHS of an intrinsic assignment", check_rhs_object_assignment) & + ,it("finalizes a non-allocatable object on the LHS of an intrinsic assignment", check_lhs_object) & ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & @@ -55,22 +55,23 @@ subroutine count_finalizations(self) self % dummy = avoid_unused_variable_warning end subroutine - function check_rhs_object_assignment() result(result_) - !! Tests 7.5.6.3 case 1 (intrinsic assignment with non-allocatable variable) + function check_lhs_object() result(result_) + !! Tests 7.5.6.3, paragraph 1 (intrinsic assignment with non-allocatable LHS variable) !! Expected: 1; gfortran 11.2: 0 type(object_t) lhs, rhs type(result_t) result_ - integer initial_tally, delta + integer initial_tally rhs%dummy = avoid_unused_variable_warning initial_tally = finalizations - lhs = rhs ! finalizes rhs - delta = finalizations - initial_tally - result_ = assert_equals(1, delta) + lhs = rhs ! finalizes lhs + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate end function function check_rhs_function_reference() result(result_) - !! Tests 7.5.6.3 case 1 (intrinsic assignment with allocated variable) + !! Tests 7.5.6.3, paragraph 5 !! Expected: 1; gfortran 11.2: 0 type(object_t), allocatable :: object type(result_t) result_ @@ -83,7 +84,7 @@ function check_rhs_function_reference() result(result_) end function function check_finalize_on_deallocate() result(result_) - !! Tests 7.5.6.3 case 2 (explicit deallocation on allocatable entity) + !! Tests 7.5.6.3, paragraph 2 (explicit deallocation on allocatable entity) type(object_t), allocatable :: object type(result_t) result_ integer initial_tally @@ -98,7 +99,7 @@ function check_finalize_on_deallocate() result(result_) end function function check_finalize_on_end() result(result_) - !! Tests 7.5.6.3 case 3 + !! Tests 7.5.6.3, paragraph 3 type(result_t) result_ integer initial_tally @@ -118,7 +119,7 @@ subroutine finalize_on_end_subroutine() end function function check_block_finalization() result(result_) - !! Tests 7.5.6.3 case 4 + !! Tests 7.5.6.3, paragraph 4 type(result_t) result_ integer initial_tally, delta @@ -132,7 +133,7 @@ function check_block_finalization() result(result_) end function function check_intent_out_finalization() result(result_) - !! Tests 7.5.6.3 case 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) + !! Tests 7.5.6.3, paragraph 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) type(result_t) result_ type(object_t) object integer initial_tally @@ -151,7 +152,7 @@ subroutine finalize_intent_out_arg(output) end function function check_allocatable_component_finalization() result(result_) - !! Tests 7.5.6.3 cases 2 (allocatable entity) & 7 + !! Tests 7.5.6.3, paragraph 2 (allocatable entity) & 7 type(wrapper_t), allocatable :: wrapper type(result_t) result_ integer initial_tally, delta From 210df41031a87c2b7fd6fd7eddddf8fbb564c33b Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Wed, 4 May 2022 18:26:35 -0700 Subject: [PATCH 21/24] test(compiler): finalize allocated allocatable LHS --- test/compiler_test.f90 | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 6dfbe57..74e50b7 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -32,13 +32,14 @@ function test_ref_reference() result(tests) tests = & describe( & "The compiler", & - [ it("finalizes an intent(out) derived type dummy argument", check_intent_out_finalization) & - ,it("finalizes an object upon explicit deallocation", check_finalize_on_deallocate) & - ,it("finalizes a non-allocatable object on the LHS of an intrinsic assignment", check_lhs_object) & + [ it("finalizes a non-allocatable object on the LHS of an intrinsic assignment", check_lhs_object) & + ,it("finalizes an allocated allocatable LHS of an intrinsic assignment", check_allocated_allocatable_lhs) & ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & + ,it("finalizes an object upon explicit deallocation", check_finalize_on_deallocate) & ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & ,it("finalizes a non-pointer non-allocatable array object at the END statement", check_finalize_on_end) & + ,it("finalizes an intent(out) derived type dummy argument", check_intent_out_finalization) & ]) end function @@ -70,6 +71,23 @@ function check_lhs_object() result(result_) end associate end function + function check_allocated_allocatable_lhs() result(result_) + !! Tests 7.5.6.3, paragraph 1 (intrinsic assignment with non-allocatable LHS variable) + !! Expected: 1; gfortran 11.2: 0 + type(object_t), allocatable :: lhs + type(object_t) rhs + type(result_t) result_ + integer initial_tally + + rhs%dummy = avoid_unused_variable_warning + initial_tally = finalizations + allocate(lhs) + lhs = rhs ! finalizes lhs + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate + end function + function check_rhs_function_reference() result(result_) !! Tests 7.5.6.3, paragraph 5 !! Expected: 1; gfortran 11.2: 0 From 7a7bd9147b3793881f6b790e3f8899c0157e3691 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Wed, 4 May 2022 18:34:09 -0700 Subject: [PATCH 22/24] refac(test): order tests by standard paragraph --- test/compiler_test.f90 | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 74e50b7..146b3fd 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -34,12 +34,12 @@ function test_ref_reference() result(tests) "The compiler", & [ it("finalizes a non-allocatable object on the LHS of an intrinsic assignment", check_lhs_object) & ,it("finalizes an allocated allocatable LHS of an intrinsic assignment", check_allocated_allocatable_lhs) & - ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & ,it("finalizes an object upon explicit deallocation", check_finalize_on_deallocate) & - ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & - ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & ,it("finalizes a non-pointer non-allocatable array object at the END statement", check_finalize_on_end) & + ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & + ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & ,it("finalizes an intent(out) derived type dummy argument", check_intent_out_finalization) & + ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & ]) end function @@ -57,8 +57,7 @@ subroutine count_finalizations(self) end subroutine function check_lhs_object() result(result_) - !! Tests 7.5.6.3, paragraph 1 (intrinsic assignment with non-allocatable LHS variable) - !! Expected: 1; gfortran 11.2: 0 + !! Verify Fortran 2018 clause 7.5.6.3, paragraph 1 behavior type(object_t) lhs, rhs type(result_t) result_ integer initial_tally @@ -72,8 +71,7 @@ function check_lhs_object() result(result_) end function function check_allocated_allocatable_lhs() result(result_) - !! Tests 7.5.6.3, paragraph 1 (intrinsic assignment with non-allocatable LHS variable) - !! Expected: 1; gfortran 11.2: 0 + !! Verify Fortran 2018 clause 7.5.6.3, paragraph 1 behavior type(object_t), allocatable :: lhs type(object_t) rhs type(result_t) result_ @@ -88,19 +86,6 @@ function check_allocated_allocatable_lhs() result(result_) end associate end function - function check_rhs_function_reference() result(result_) - !! Tests 7.5.6.3, paragraph 5 - !! Expected: 1; gfortran 11.2: 0 - type(object_t), allocatable :: object - type(result_t) result_ - integer initial_tally, delta - - initial_tally = finalizations - object = object_t() ! finalizes object_t result - delta = finalizations - initial_tally - result_ = assert_equals(1, delta) - end function - function check_finalize_on_deallocate() result(result_) !! Tests 7.5.6.3, paragraph 2 (explicit deallocation on allocatable entity) type(object_t), allocatable :: object @@ -150,6 +135,18 @@ function check_block_finalization() result(result_) result_ = assert_equals(1, delta) end function + function check_rhs_function_reference() result(result_) + !! Verify Fortran 2018 clause 7.5.6.3, paragraph 5 behavior + type(object_t), allocatable :: object + type(result_t) result_ + integer initial_tally, delta + + initial_tally = finalizations + object = object_t() ! finalizes object_t result + delta = finalizations - initial_tally + result_ = assert_equals(1, delta) + end function + function check_intent_out_finalization() result(result_) !! Tests 7.5.6.3, paragraph 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) type(result_t) result_ From 922e5cac9388d76f22d3cb81812e8afce477b55a Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Wed, 4 May 2022 18:53:46 -0700 Subject: [PATCH 23/24] test(compiler): finalize specification expression --- test/compiler_test.f90 | 56 ++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 146b3fd..200652d 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -6,16 +6,11 @@ module compiler_test public :: test_ref_reference type object_t - private integer dummy contains final :: count_finalizations end type - interface object_t - module procedure construct_object - end interface - type wrapper_t private type(object_t), allocatable :: object @@ -38,6 +33,7 @@ function test_ref_reference() result(tests) ,it("finalizes a non-pointer non-allocatable array object at the END statement", check_finalize_on_end) & ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & ,it("finalizes a function reference on the RHS of an intrinsic assignment", check_rhs_function_reference) & + ,it("finalizes a specification expression function result", check_specification_expression) & ,it("finalizes an intent(out) derived type dummy argument", check_intent_out_finalization) & ,it("finalizes an allocatable component object", check_allocatable_component_finalization) & ]) @@ -124,27 +120,49 @@ subroutine finalize_on_end_subroutine() function check_block_finalization() result(result_) !! Tests 7.5.6.3, paragraph 4 type(result_t) result_ - integer initial_tally, delta + integer initial_tally initial_tally = finalizations block type(object_t) object object % dummy = avoid_unused_variable_warning end block ! Finalizes object - delta = finalizations - initial_tally - result_ = assert_equals(1, delta) + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate end function function check_rhs_function_reference() result(result_) !! Verify Fortran 2018 clause 7.5.6.3, paragraph 5 behavior type(object_t), allocatable :: object type(result_t) result_ - integer initial_tally, delta + integer initial_tally initial_tally = finalizations - object = object_t() ! finalizes object_t result - delta = finalizations - initial_tally - result_ = assert_equals(1, delta) + object = construct_object() ! finalizes object_t result + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate + end function + + function check_specification_expression() result(result_) + !! Tests 7.5.6.3, paragraph 6 + type(result_t) result_ + integer initial_tally + + initial_tally = finalizations + call finalize_specification_expression + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate + + contains + + subroutine finalize_specification_expression + type(object_t) :: object = object_t(dummy=0) ! Finalizes RHS function reference + object%dummy = avoid_unused_variable_warning + end subroutine + end function function check_intent_out_finalization() result(result_) @@ -155,30 +173,30 @@ function check_intent_out_finalization() result(result_) initial_tally = finalizations call finalize_intent_out_arg(object) - result_ = assert_equals(initial_tally+1, finalizations) - + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate contains - subroutine finalize_intent_out_arg(output) type(object_t), intent(out) :: output ! finalizes output output%dummy = avoid_unused_variable_warning end subroutine - end function function check_allocatable_component_finalization() result(result_) !! Tests 7.5.6.3, paragraph 2 (allocatable entity) & 7 type(wrapper_t), allocatable :: wrapper type(result_t) result_ - integer initial_tally, delta + integer initial_tally initial_tally = finalizations allocate(wrapper) allocate(wrapper%object) call finalize_intent_out_component(wrapper) - delta = finalizations - initial_tally - result_ = assert_equals(1, delta) + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate contains From bc4a5fc74ae2506bab45f0d801242a2c57474a00 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Wed, 4 May 2022 19:27:22 -0700 Subject: [PATCH 24/24] test(compiler): finish finalization scenarios --- test/compiler_test.f90 | 82 +++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/test/compiler_test.f90 b/test/compiler_test.f90 index 200652d..e7cdaf6 100644 --- a/test/compiler_test.f90 +++ b/test/compiler_test.f90 @@ -29,6 +29,7 @@ function test_ref_reference() result(tests) "The compiler", & [ it("finalizes a non-allocatable object on the LHS of an intrinsic assignment", check_lhs_object) & ,it("finalizes an allocated allocatable LHS of an intrinsic assignment", check_allocated_allocatable_lhs) & + ,it("finalizes a target when the associated pointer is deallocated", check_target_deallocation) & ,it("finalizes an object upon explicit deallocation", check_finalize_on_deallocate) & ,it("finalizes a non-pointer non-allocatable array object at the END statement", check_finalize_on_end) & ,it("finalizes a non-pointer non-allocatable object at the end of a block construct", check_block_finalization) & @@ -53,7 +54,7 @@ subroutine count_finalizations(self) end subroutine function check_lhs_object() result(result_) - !! Verify Fortran 2018 clause 7.5.6.3, paragraph 1 behavior + !! Verify Fortran 2018 clause 7.5.6.3, paragraph 1 behavior: "not an unallocated allocatable variable" type(object_t) lhs, rhs type(result_t) result_ integer initial_tally @@ -67,7 +68,7 @@ function check_lhs_object() result(result_) end function function check_allocated_allocatable_lhs() result(result_) - !! Verify Fortran 2018 clause 7.5.6.3, paragraph 1 behavior + !! Verify Fortran 2018 clause 7.5.6.3, paragraph 1 behavior: "allocated allocatable variable" type(object_t), allocatable :: lhs type(object_t) rhs type(result_t) result_ @@ -82,8 +83,48 @@ function check_allocated_allocatable_lhs() result(result_) end associate end function + function check_target_deallocation() result(result_) + !! Verify Fortran 2018 clause 7.5.6.3, paragraph 2 behavior: "pointer is deallocated" + type(object_t), pointer :: object_ptr => null() + type(result_t) result_ + integer initial_tally + + allocate(object_ptr, source=object_t(dummy=0)) + initial_tally = finalizations + deallocate(object_ptr) ! finalizes object + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate + end function + + function check_allocatable_component_finalization() result(result_) + !! Tests 7.5.6.3, para. 2 ("allocatable entity is deallocated") + !! + 9.7.3.2, para. 6 ("INTENT(OUT) allocatable dummy argument is deallocated") + type(wrapper_t), allocatable :: wrapper + type(result_t) result_ + integer initial_tally + + initial_tally = finalizations + + allocate(wrapper) + allocate(wrapper%object) + call finalize_intent_out_component(wrapper) + associate(delta => finalizations - initial_tally) + result_ = assert_equals(1, delta) + end associate + + contains + + subroutine finalize_intent_out_component(output) + type(wrapper_t), intent(out) :: output ! finalizes object component + allocate(output%object) + output%object%dummy = avoid_unused_variable_warning + end subroutine + + end function + function check_finalize_on_deallocate() result(result_) - !! Tests 7.5.6.3, paragraph 2 (explicit deallocation on allocatable entity) + !! Tests 7.5.6.3, paragraph 2: "allocatable entity is deallocated" type(object_t), allocatable :: object type(result_t) result_ integer initial_tally @@ -98,7 +139,7 @@ function check_finalize_on_deallocate() result(result_) end function function check_finalize_on_end() result(result_) - !! Tests 7.5.6.3, paragraph 3 + !! Tests 7.5.6.3, paragraph 3: "before return or END statement" type(result_t) result_ integer initial_tally @@ -118,7 +159,7 @@ subroutine finalize_on_end_subroutine() end function function check_block_finalization() result(result_) - !! Tests 7.5.6.3, paragraph 4 + !! Tests 7.5.6.3, paragraph 4: "termination of the BLOCK construct" type(result_t) result_ integer initial_tally @@ -133,7 +174,7 @@ function check_block_finalization() result(result_) end function function check_rhs_function_reference() result(result_) - !! Verify Fortran 2018 clause 7.5.6.3, paragraph 5 behavior + !! Verify Fortran 2018 clause 7.5.6.3, paragraph 5 behavior: "nonpointer function result" type(object_t), allocatable :: object type(result_t) result_ integer initial_tally @@ -146,7 +187,7 @@ function check_rhs_function_reference() result(result_) end function function check_specification_expression() result(result_) - !! Tests 7.5.6.3, paragraph 6 + !! Tests 7.5.6.3, paragraph 6: "specification expression function result" type(result_t) result_ integer initial_tally @@ -166,7 +207,7 @@ subroutine finalize_specification_expression end function function check_intent_out_finalization() result(result_) - !! Tests 7.5.6.3, paragraph 7 (non-pointer non-allocatable INTENT(OUT) dummy argument) + !! Tests 7.5.6.3, paragraph 7: "nonpointer, nonallocatable, INTENT (OUT) dummy argument" type(result_t) result_ type(object_t) object integer initial_tally @@ -183,29 +224,4 @@ subroutine finalize_intent_out_arg(output) end subroutine end function - function check_allocatable_component_finalization() result(result_) - !! Tests 7.5.6.3, paragraph 2 (allocatable entity) & 7 - type(wrapper_t), allocatable :: wrapper - type(result_t) result_ - integer initial_tally - - initial_tally = finalizations - - allocate(wrapper) - allocate(wrapper%object) - call finalize_intent_out_component(wrapper) - associate(delta => finalizations - initial_tally) - result_ = assert_equals(1, delta) - end associate - - contains - - subroutine finalize_intent_out_component(output) - type(wrapper_t), intent(out) :: output ! finalizes object component - allocate(output%object) - output%object%dummy = avoid_unused_variable_warning - end subroutine - - end function - end module compiler_test