Skip to content

Commit 98c11fe

Browse files
committed
[Fortran/gfortran] Fix build-time and test-time race conditions
Use a dedicated module directory for each test. Any .mod files generated by the test at build-time will be written into this directory. The same directory is also used as the working directory for the the tests at test-time. Any files created/read/written by the test at test-time reside in that directory. This ensures that the tests don't race on the file system when run in parallel. The tests that were previously disabled because of these races have been re-enabled. This fixes PR #63263 (llvm/llvm-project#63263) Differential Revision: https://reviews.llvm.org/D152307
1 parent 23cd352 commit 98c11fe

File tree

3 files changed

+31
-54
lines changed

3 files changed

+31
-54
lines changed

Fortran/gfortran/CMakeLists.txt

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,11 @@ endfunction()
239239

240240
function(gfortran_execute_test File)
241241
cmake_parse_arguments(GFORTRAN "" "PREFIX" "FFLAGS;LDFLAGS;DEPFILES" ${ARGN})
242-
# There are a few tests with duplicate filenames, and CMake wants all target
243-
# names to be unique, so we add a disambiguator to the target name. The
242+
# There are a few tests - in different directories - with duplicate filenames.
243+
# CMake requires all target names to be unique, so we add a disambiguator. The
244244
# disambiguator uses the path of the file relative to the top-level directory
245-
# containing all the tests from the gfortran test suite.
245+
# containing all the tests from the gfortran test suite to ensure that
246+
# targets in different directories will have distinct names.
246247

247248
# The ${File} argument is guaranteed to be the absolute path to the source
248249
# file.
@@ -260,19 +261,38 @@ function(gfortran_execute_test File)
260261
# tests.
261262
string(REPLACE "." "_" Name "${Name}")
262263

263-
set(_target "${GFORTRAN_PREFIX}-${Name}")
264+
set(test_target "${GFORTRAN_PREFIX}-${Name}")
265+
set(working_dir_name "${test_target}.wd")
266+
set(working_dir "${CMAKE_CURRENT_BINARY_DIR}/${working_dir_name}")
264267

268+
# Several tests in the suite build modules with the same name at build-time.
269+
# Others create/write/read files with the same name at test-time. In either
270+
# case, these are race conditions which can lead to non-deterministic failures
271+
# at build and/or test time. To work around this, have each test run in its
272+
# own directory.
273+
#
274+
# This directory is also used as module directory at build-time.
275+
#
276+
# It may be "cleaner" to have separate directories - one that serves as the
277+
# module directory and the other as the working directory, but that is
278+
# probably unnecessary.
279+
file(MAKE_DIRECTORY ${working_dir})
280+
281+
# Parse the dg-options annotations in the file and add it to DG_FFLAGS.
265282
gfortran_dg_options_fflags(DG_FFLAGS ${File})
266283

267-
# Add any flags that were requested
284+
# Add any flags that were requested.
268285
list(APPEND FFLAGS ${DG_FFLAGS} ${GFORTRAN_FFLAGS})
269286
list(APPEND LDFLAGS ${GFORTRAN_LDFLAGS})
270287

271-
llvm_test_executable_no_test(${_target} ${File} ${GFORTRAN_DEPFILES})
272-
llvm_test_run()
288+
llvm_test_executable_no_test(${test_target} ${File} ${GFORTRAN_DEPFILES})
289+
llvm_test_run(WORKDIR "%S/${working_dir_name}")
290+
llvm_add_test_for_target(${test_target})
273291

274-
llvm_add_test_for_target(${_target})
275-
target_include_directories(${_target} PRIVATE ${ISO_FORTRAN_C_HEADER_DIR})
292+
target_include_directories(${test_target}
293+
PRIVATE ${ISO_FORTRAN_C_HEADER_DIR} ${working_dir})
294+
set_target_properties(${test_target} PROPERTIES
295+
Fortran_MODULE_DIRECTORY ${working_dir})
276296

277297
# This is a workaround because cmake does not currently recognize the .f03
278298
# and .f08 extensions. A patch to fix cmake has been accepted and the fix
@@ -292,8 +312,8 @@ function(gfortran_execute_test File)
292312

293313
# NOTE: This should be removed when the -flang-experimental-exec flag is no
294314
# longer needed.
295-
target_link_options(${_target} PRIVATE -flang-experimental-exec)
296-
set_target_properties(${_target} PROPERTIES LINKER_LANGUAGE Fortran)
315+
target_link_options(${test_target} PRIVATE -flang-experimental-exec)
316+
set_target_properties(${test_target} PROPERTIES LINKER_LANGUAGE Fortran)
297317
endfunction()
298318

299319
add_subdirectory(regression)

Fortran/gfortran/regression/CMakeLists.txt

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,41 +1845,6 @@ file(GLOB Failing CONFIGURE_DEPENDS
18451845
# anyway so the test-suite passes by default on AArch64.
18461846
entry_23.f
18471847
findloc_8.f90
1848-
1849-
# These tests have race conditions with other tests that cause them to
1850-
# occasionally fail when run in parallel. Every test in each group listed
1851-
# below has a race condition with at least one other test in the group.
1852-
1853-
# <group> Tests read/write/replace/delete file named 'tmp.dat'
1854-
pr88169_1.f90
1855-
pr88169_2.f90
1856-
pr88169_3.f90
1857-
list_read_6.f90
1858-
# </group>
1859-
1860-
# <group>
1861-
write_rewind_1.f
1862-
write_rewind_2.f
1863-
# </group>
1864-
1865-
# <group> Tests read/delete/append file named 'foo'
1866-
append_1.f90
1867-
large_unit_2.f90
1868-
open_access_append_1.f90
1869-
open_status_1.f90
1870-
# </group>
1871-
1872-
# <group> Tests create/replace file named 'test.dat'
1873-
direct_io_12.f90
1874-
endfile.f90
1875-
eof_4.f90
1876-
implied_do_io_1.f90
1877-
list_read_7.f90
1878-
namelist_76.f90
1879-
read_eof_8.f90
1880-
read_eof_all.f90
1881-
streamio_18.f90
1882-
# </group>
18831848
)
18841849

18851850
list(APPEND UnsupportedTests "${Unsupported}")

Fortran/gfortran/torture/execute/CMakeLists.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,6 @@ file(GLOB Skipped CONFIGURE_DEPENDS
104104

105105
# error: '[SYM]' is not a known intrinsic procedure
106106
specifics.f90
107-
108-
# --------------------------------------------------------------------------
109-
#
110-
# These tests are skipped because they generate the same module as other
111-
# tests in this directory and create non-deterministic conflicts when building
112-
# in parallel.
113-
114-
module_init_1.f90 # Conflicts with function_module_1.f90
115107
)
116108

117109
# These tests are disabled because they fail at runtime when they should pass.

0 commit comments

Comments
 (0)