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])




Reply via email to