On 32-bit mingw (both mingw 5.0.3 and mingw 10.0.0), I see these test failures:
FAIL: test-timespec_get ======================= ../../gltests/test-timespec_get.c:52: assertion 'ts1.tv_sec <= tt2' failed FAIL test-timespec_get.exe (exit status: 3) FAIL: test-timespec_getres ========================== ../../gltests/test-timespec_getres.c:37: assertion 'ts.tv_sec == 0 ? 0 < ts.tv_nsec && ts.tv_nsec < 1000000000 : ts.tv_sec == 1 && ts.tv_nsec == 0' failed FAIL test-timespec_getres.exe (exit status: 3) After adding a printf to test-timespec_get.c, that prints the returned 'time_t tv_sec' part in hexadecimal, I see this output in consecutive runs: ts1 = 1bec9e1864d5e93f.000000000 tt2 = 64d5e93f ts1 = 865b37064d5e943.000000000 tt2 = 64d5e943 ts1 = 3ab7820464d5e945.000000000 tt2 = 64d5e945 ts1 = 3069e1fc64d5e946.000000000 tt2 = 64d5e946 So, the upper half bits of the 'time_t tv_sec' part are uninitialized. The clock_gettime function on mingw comes from libwinpthread. Apparently, this library was built with a 32-bit time_t. But Gnulib's year2038 modules enforces a 64-bit time_t, through -D__MINGW_USE_VC2005_COMPAT. Thus, we cannot use time related functions from this library. (And the thread- related functions of this library are buggy, see <https://lists.gnu.org/archive/html/bug-gnulib/2023-04/msg00176.html>.) This patch fixes both test failures. 2023-08-11 Bruno Haible <br...@clisp.org> clock-time: On mingw, avoid buggy clock_gettime from libwinpthread. * m4/clock_time.m4 (gl_CLOCK_TIME): Require AC_CANONICAL_HOST. On native Windows, avoid using clock_getres clock_gettime clock_settime from mingw's libwinpthread. * doc/posix-functions/clock_gettime.texi: Mention the mingw bug. diff --git a/doc/posix-functions/clock_gettime.texi b/doc/posix-functions/clock_gettime.texi index 93ac4215df..890bbfcc53 100644 --- a/doc/posix-functions/clock_gettime.texi +++ b/doc/posix-functions/clock_gettime.texi @@ -15,6 +15,10 @@ @item This function is missing on some platforms: Mac OS X 10.11, Minix 3.1.8, mingw, MSVC 14. +@item +This function leaves the upper 32 bits of the @code{tv_sec} field of the result +uninitialized on some platforms: +mingw in 32-bit mode. @end itemize The Gnulib modules @code{gettime} and @code{timespec_get} are partial diff --git a/m4/clock_time.m4 b/m4/clock_time.m4 index d624a73d35..28534db1c7 100644 --- a/m4/clock_time.m4 +++ b/m4/clock_time.m4 @@ -1,4 +1,4 @@ -# clock_time.m4 serial 12 +# clock_time.m4 serial 13 dnl Copyright (C) 2002-2006, 2009-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -12,9 +12,17 @@ AC_DEFUN([gl_CLOCK_TIME], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + dnl Persuade glibc and Solaris <time.h> to declare these functions. AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + # On mingw, these functions are defined in the libwinpthread library, + # which is better avoided. In fact, the clock_gettime function is buggy + # in 32-bit mingw, when -D__MINGW_USE_VC2005_COMPAT is used (which Gnulib's + # year2038 module does): It leaves the upper 32 bits of the tv_sec field + # of the result uninitialized. + # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function. # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4. @@ -23,12 +31,22 @@ AC_DEFUN([gl_CLOCK_TIME] # library, inducing unnecessary run-time overhead. CLOCK_TIME_LIB= AC_SUBST([CLOCK_TIME_LIB]) - gl_saved_libs=$LIBS - AC_SEARCH_LIBS([clock_gettime], [rt posix4], - [test "$ac_cv_search_clock_gettime" = "none required" || - CLOCK_TIME_LIB=$ac_cv_search_clock_gettime]) - AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime]) - LIBS=$gl_saved_libs + case "$host_os" in + mingw*) + ac_cv_func_clock_getres=no + ac_cv_func_clock_gettime=no + ac_cv_func_clock_settime=no + ;; + *) + gl_saved_libs=$LIBS + AC_SEARCH_LIBS([clock_gettime], [rt posix4], + [test "$ac_cv_search_clock_gettime" = "none required" || + CLOCK_TIME_LIB=$ac_cv_search_clock_gettime]) + AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime]) + LIBS=$gl_saved_libs + ;; + esac + # For backward compatibility. LIB_CLOCK_GETTIME="$CLOCK_TIME_LIB" AC_SUBST([LIB_CLOCK_GETTIME])