|
| 1 | +Finalization Unit Tests |
| 2 | +======================= |
| 3 | + |
| 4 | +This suite of tests was created originally by Wileam Phan, Damian Rouson, |
| 5 | +and Brad Richardson as part of the |
| 6 | +[[ https://github.com/sourceryinstitute/smart-pointers | Smart-Pointers ]] |
| 7 | +library's test suite. |
| 8 | +All compilers, except for NAG, did not initially have a working/correct |
| 9 | +implmentation of finalization. |
| 10 | +An all-in-one reproducer test was created to share with compiler |
| 11 | +teams that was easy to run (just compile a single file and run it). |
| 12 | +This is ideal for reporting bugs to compiler teams, |
| 13 | +but not appropriate for inclusion in a compiler test suite. |
| 14 | + |
| 15 | +The original adaptation for inclusion in the llvm-test-suite can be found here: |
| 16 | + |
| 17 | +* https://github.com/BerkeleyLab/llvm-test-suite/tree/damians-fortran-type-finalization |
| 18 | + SHA: `0268bcf0048e67cd1280f9ef65aebd2aa402130b` |
| 19 | +* https://github.com/BerkeleyLab/llvm-test-suite/tree/berkely-lab-damian-v0.1 |
| 20 | + SHA: `0268bcf0048e67cd1280f9ef65aebd2aa402130b` |
| 21 | + |
| 22 | +The test suite was then adapted to be made appropriate for inclusion |
| 23 | +in a compiler test suite by Izaak Beekman. |
| 24 | +Broadly, this required: |
| 25 | + |
| 26 | +- Each test should be broken into in individual file. |
| 27 | +- Each test should have a corresponding expected output. |
| 28 | +- Use the compilers build system rather than a custom fortran driver program |
| 29 | + (relying) on `execute_command_line`. |
| 30 | +- The tests should be incorporated following the conventions adopted by the |
| 31 | + compiler project. |
| 32 | +- The README/documentation should be updated and made appropriate for keeping |
| 33 | + in the compiler project's test suite repository. |
| 34 | + - e.g., Describe the tests and how to use them |
| 35 | + - Don't keep information about what version of which compiler works since |
| 36 | + it will get stale quickly and be a maintainance headache. |
| 37 | + |
| 38 | +To run these finalization tests, and only these tests, |
| 39 | +first you must build a recent version of llvm flang. |
| 40 | +LLVM version d585a8afdf2f70159759dccb11d775cdf432aba4, |
| 41 | +from Fri Apr 7 18:12:12 2023 +0000 is known to work. |
| 42 | +Newer versions should work as well unless a regression is introduced. |
| 43 | + |
| 44 | +You can setup your directory structure as follows: |
| 45 | + |
| 46 | +``` |
| 47 | +llvm-project # llvm-project/llvm source code |
| 48 | +├── build # Build directory for llvm-project/flang |
| 49 | +├── test-suite # llvm-project/llvm-test-suite source code |
| 50 | +└── test-suite-build # Build directory for test-suite |
| 51 | +``` |
| 52 | + |
| 53 | +Flang is built in the `build` subdirectory. |
| 54 | +The test-suite-build directory is created by the user |
| 55 | +and is initially empty until running CMake for the teset-suite. |
| 56 | +To configure, build and run the tests once llvm/flang has been built, |
| 57 | +a command similar to the following can be used from within test-suite-build: |
| 58 | + |
| 59 | +``` shell |
| 60 | +cmake -DCMAKE_BUILD_TYPE=Release \ |
| 61 | + -DCMAKE_Fortran_COMPILER:FILEPATH=/home/users/<you>/llvm-project/build/bin/flang-new \ |
| 62 | + -DCMAKE_Fortran_FLAGS=-flang-experimental-exec \ |
| 63 | + -DTEST_SUITE_FORTRAN:BOOL=On \ |
| 64 | + -DTEST_SUITE_SUBDIRS=Fortran/UnitTests/finalization \ |
| 65 | + ../test-suite |
| 66 | +make -j 4 |
| 67 | +../build/bin/llvm-lit Fortran/UnitTests/finalization |
| 68 | +``` |
| 69 | + |
| 70 | +Summary of Tests |
| 71 | +---------------- |
| 72 | + |
| 73 | +* [`allocatable_component.f90`] |
| 74 | + * Finalizes an allocatable component object on deallocation of an intent out dymmy argument |
| 75 | + * Test conformance with Fortran 2018 clause 7.5.6.3, para. 2 ("allocatable entity is deallocated") |
| 76 | + + 9.7.3.2, para. 6 ("INTENT(OUT) allocatable dummy argument is deallocated") |
| 77 | +* [`allocated_allocatable_lhs.f90`] |
| 78 | + * Finalizes an allocated allocatable LHS of an intrinsic assignment |
| 79 | + * Test conformance with Fortran 2018 clause 7.5.6.3, paragraph 1 behavior: |
| 80 | + "allocated allocatable variable" |
| 81 | +* [`block_end.f90`] |
| 82 | + * Finalizes a non-pointer non-allocatable object at the end of a block construct |
| 83 | + * Test conformance with Fortran 2018 clause 7.5.6.3, paragraph 4: |
| 84 | + "termination of the BLOCK construct" |
| 85 | +* [`finalize_on_deallocate.f90`] |
| 86 | + * Finalizes an object upon explicit deallocation |
| 87 | + * Test conformance with Fortran 2018 clause 7.5.6.3, paragraph 2: |
| 88 | + "allocatable entity is deallocated" |
| 89 | +* [`finalize_on_end.f90`] |
| 90 | + * finalizes a non-pointer non-allocatable object at the END statement |
| 91 | + * Test conformance with Fortran 2018 clause 7.5.6.3, paragraph 3: |
| 92 | + "before return or END statement" |
| 93 | +* [`intent_out.f90`] |
| 94 | + * Finalizes an intent(out) derived type dummy argument |
| 95 | + * Test conformance with Fortran 2018 standard clause 7.5.6.3, paragraph 7: |
| 96 | + "nonpointer, nonallocatable, INTENT (OUT) dummy argument" |
| 97 | +* [`lhs_object.f90`] |
| 98 | + * Finalizes a non-allocatable object on the LHS of an intrinsic assignment |
| 99 | + * Test conformance with Fortran 2018 clause 7.5.6.3, paragraph 1 behavior: |
| 100 | + "not an unallocated allocatable variable" |
| 101 | +* [`rhs_function_reference.f90`] |
| 102 | + * Finalizes a function reference on the RHS of an intrinsic assignment |
| 103 | + * Test conformance with Fortran 2018 clause 7.5.6.3, paragraph 5 behavior: |
| 104 | + "nonpointer function result" |
| 105 | +* [`specification_expression_finalization.f90`] |
| 106 | + * Finalizes a function result in a specification expression |
| 107 | + * Test compiler conformance with clause 7.5.6.3, paragraph 6 in the Fortran |
| 108 | + Interpretation Document (https://j3-fortran.org/doc/year/18/18-007r1.pdf): |
| 109 | + "If a specification expression in a scoping unit references |
| 110 | + a function, the result is finalized before execution of the executable |
| 111 | + constructs in the scoping unit." (The same statement appears in clause |
| 112 | + 4.5.5.2, paragraph 5 of the Fortran 2003 standard.) In such a scenario, |
| 113 | + the final subroutine must be pure. The only way to observe output from |
| 114 | + a pure final subroutine is for the subroutine to execute an error stop |
| 115 | + statement. A correct execution of this test will error-terminate and ouput |
| 116 | + the text "finalize: intentional error termination to verify finalization". |
| 117 | +* [`target_deallocation.f90`] |
| 118 | + * Finalizes a target when the associated pointer is deallocated |
| 119 | + * Test conformance with Fortran 2018 clause 7.5.6.3, paragraph 2 behavior: |
| 120 | + "pointer is deallocated" |
| 121 | + |
| 122 | + |
| 123 | +Common Code |
| 124 | +----------- |
| 125 | + |
| 126 | +* [`object_type_m.f90`] |
| 127 | + * To reduce code duplication, yet allow each test to be treated by |
| 128 | + CMake as a single source file, a small amount of common code is |
| 129 | + `include`d from this file by each test file. |
| 130 | + * Due to the way CMake handles `.mod` module files, it is important |
| 131 | + that each of the test files uses unique module names, otherwise |
| 132 | + CMake will encounter a race condition when building in parallel |
| 133 | + wherein it might clobber a `.mod` module file or corresponding |
| 134 | + timestamp when multiple `.mod` files are being created with the |
| 135 | + same name. |
| 136 | + * This file contains the main derived type object for testing and the |
| 137 | + corresponding final subroutine, `count_finalizations` to verify that |
| 138 | + finalization took pace (by counting finalizations in a public module |
| 139 | + variable) |
| 140 | + |
| 141 | +[`allocatable_component.f90`]: ./allocatable_component.f90 |
| 142 | +[`allocated_allocatable_lhs.f90`]: ./allocated_allocatable_lhs.f90 |
| 143 | +[`block_end.f90`]: ./block_end.f90 |
| 144 | +[`finalize_on_deallocate.f90`]: ./finalize_on_deallocate.f90 |
| 145 | +[`finalize_on_end.f90`]: ./finalize_on_end.f90 |
| 146 | +[`intent_out.f90`]: ./intent_out.f90 |
| 147 | +[`lhs_object.f90`]: ./lhs_object.f90 |
| 148 | +[`rhs_function_reference.f90`]: ./rhs_function_reference.f90 |
| 149 | +[`specification_expression_finalization.f90`]: ./specification_expression_finalization.f90 |
| 150 | +[`target_deallocation.f90`]: ./target_deallocation.f90 |
| 151 | +[`object_type_m.f90`]: ./object_type_m.f90 |
0 commit comments