On Mon, 2 Nov 2026, Harald Anlauf wrote:
> Hi Richard!
>
> Am 31.10.26 um 7:57 PM schrieb Richard Biener:
> > PR114895 reports that on 32-bit glibc targets with 32-bit time_t, stat()
> > fails with EOVERFLOW once file timestamps are past 2038-01-19.
> > The LIBGFOR_CHECK_WORKING_STAT configure test then fails, HAVE_WORKING_STAT
> > is left undefined, and the build of io/unix.c breaks, since the
> > !HAVE_WORKING_STAT code path there is only usable on MinGW.
> > This can be reproduced e.g. by building the 32-bit multilib in a VM whose
> > clock is set past 2038.
> >
> > Fix this by building libgfortran with 64-bit time_t where the C library
> > supports it as requested by PR103886. A new LIBGFOR_CHECK_TIME_BITS64
> > check, run right after AC_SYS_LARGEFILE, tests whether time_t is already
> > 64 bits wide and, if not, whether defining _TIME_BITS to 64 makes it so;
> > in that case _TIME_BITS is defined to 64 in config.h. glibc only accepts
> > _TIME_BITS=64 together with _FILE_OFFSET_BITS=64, so the check relies on
> > the _FILE_OFFSET_BITS setting from AC_SYS_LARGEFILE and does nothing
> > when configured with --disable-largefile.
> >
> > No exported libgfortran interface uses time_t, struct stat or other
> > time-related C types; the time_t uses are all in internal helpers, so
> > the library ABI does not change. Note that intrinsics returning or
> > taking default-kind INTEGER values (e.g. TIME, or STAT with an INTEGER(4)
> > array) still truncate to 32 bits; this change only makes the internal
> > handling and the 64-bit variants correct past 2038.
> >
> > Bootstrap and regtest running on x86_64-unknown-linux-gnu. I'll see
> > to also somehow test a native i?86 build (the x86_64 32bit multilib
> > exercises it though).
Meanwhile also tested natively on i?86-linux-gnu.
> > Given the toplevel configure.ac --disable-year2038
> > and it's comments I've opted for selectively enabling libgfortran since
> > it is one of the target libraries which suffers from issues but switching
> > has no effects on its ABI (and it has that build failure recorded in
> > PR114895). Also PR114065 reports Ada will fail to build with
> > -D_TIME_BITS=64 ...
> >
> > OK for trunk?
>
> I am not really an expert in this area, but then nobody has stepped
> in so far.
>
> I think this is OK. There are other (non-standard) intrinsics, like
> TIME8(), which allow the user to handle date past the critical one.
> Users with legacy codes will have to audit them anyway in the coming
> 11 years... We may add a notice to the 17.x release notes with the
> above info.
>
> You may wait for another 24h or so to see if someone else sees a
> critical issue.
I'll wait a bit longer for input, thanks for your review.
Richard.
> Thanks,
> Harald
>
> > Thanks,
> > Richard.
> >
> > PR libfortran/103886
> > PR libfortran/114895
> > libgfortran/
> > * acinclude.m4 (LIBGFOR_CHECK_TIME_BITS64): New check for
> > 64-bit time_t support.
> > * configure.ac: Invoke LIBGFOR_CHECK_TIME_BITS64.
> > * configure: Regenerate.
> > * config.h.in: Regenerate.
> > ---
> > libgfortran/acinclude.m4 | 25 ++++++++++++++++
> > libgfortran/config.h.in | 3 ++
> > libgfortran/configure | 62 ++++++++++++++++++++++++++++++++++++++++
> > libgfortran/configure.ac | 1 +
> > 4 files changed, 91 insertions(+)
> >
> > diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4
> > index 118bed2b41b..890516a6aed 100644
> > --- a/libgfortran/acinclude.m4
> > +++ b/libgfortran/acinclude.m4
> > @@ -178,6 +178,31 @@ if test x"$libgfor_cv_have_crlf" = xyes; then
> > AC_DEFINE(HAVE_CRLF, 1, [Define if CRLF is line terminator.])
> > fi])
> >
> > +dnl Check for 64-bit time_t support on 32-bit platforms (Y2038 safety).
> > +dnl glibc only accepts _TIME_BITS=64 together with _FILE_OFFSET_BITS=64,
> > +dnl so rely on AC_SYS_LARGEFILE having put the latter into confdefs.h;
> > +dnl with --disable-largefile the probe fails and _TIME_BITS is not set.
> > +AC_DEFUN([LIBGFOR_CHECK_TIME_BITS64], [
> > + AC_REQUIRE([AC_SYS_LARGEFILE])
> > + AC_CACHE_CHECK([for 64-bit time_t], [libgfor_cv_time_bits64], [
> > + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
> > +#include <time.h>
> > +#include <sys/types.h>
> > +int verify_y2038[(sizeof (time_t) >= 8) ? 1 : -1];
> > +]])], [libgfor_cv_time_bits64="already 64-bit"], [
> > + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
> > +#define _TIME_BITS 64
> > +#include <time.h>
> > +#include <sys/types.h>
> > +int verify_y2038[(sizeof (time_t) >= 8) ? 1 : -1];
> > +]])], [libgfor_cv_time_bits64="yes"], [libgfor_cv_time_bits64="no"])
> > + ])
> > + ])
> > + if test "x$libgfor_cv_time_bits64" = xyes; then
> > + AC_DEFINE([_TIME_BITS], [64], [Define to 64 to enable 64-bit time_t on
> > 32-bit systems.])
> > + fi
> > +])
> > +
> > dnl Check whether the st_ino and st_dev stat fields taken together
> > uniquely
> > dnl identify the file within the system. This is should be true for POSIX
> > dnl systems; it is known to be false on mingw32.
> > diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
> > index 1d4bbfbb4a9..7a57b9a6208 100644
> > --- a/libgfortran/config.h.in
> > +++ b/libgfortran/config.h.in
> > @@ -1266,6 +1266,9 @@
> > /* Define to 1 if you need to in order for `stat' and other things to
> > work. */
> > #undef _POSIX_SOURCE
> >
> > +/* Define to 64 to enable 64-bit time_t on 32-bit systems. */
> > +#undef _TIME_BITS
> > +
> > /* Define to the type of a signed integer type wide enough to hold a
> > pointer,
> > if such a type exists, and if the system does not define it. */
> > #undef intptr_t
> > diff --git a/libgfortran/configure b/libgfortran/configure
> > index c7d2c6666bf..6aeba503714 100755
> > --- a/libgfortran/configure
> > +++ b/libgfortran/configure
> > @@ -16987,6 +16987,68 @@ rm -rf conftest*
> > fi
> >
> >
> > +
> > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit time_t" >&5
> > +$as_echo_n "checking for 64-bit time_t... " >&6; }
> > +if ${libgfor_cv_time_bits64+:} false; then :
> > + $as_echo_n "(cached) " >&6
> > +else
> > +
> > + cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> > +/* end confdefs.h. */
> > +
> > +#include <time.h>
> > +#include <sys/types.h>
> > +int verify_y2038[(sizeof (time_t) >= 8) ? 1 : -1];
> > +
> > +int
> > +main ()
> > +{
> > +
> > + ;
> > + return 0;
> > +}
> > +_ACEOF
> > +if ac_fn_c_try_compile "$LINENO"; then :
> > + libgfor_cv_time_bits64="already 64-bit"
> > +else
> > +
> > + cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> > +/* end confdefs.h. */
> > +
> > +#define _TIME_BITS 64
> > +#include <time.h>
> > +#include <sys/types.h>
> > +int verify_y2038[(sizeof (time_t) >= 8) ? 1 : -1];
> > +
> > +int
> > +main ()
> > +{
> > +
> > + ;
> > + return 0;
> > +}
> > +_ACEOF
> > +if ac_fn_c_try_compile "$LINENO"; then :
> > + libgfor_cv_time_bits64="yes"
> > +else
> > + libgfor_cv_time_bits64="no"
> > +fi
> > +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> > +
> > +fi
> > +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> > +
> > +fi
> > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgfor_cv_time_bits64"
> > >&5
> > +$as_echo "$libgfor_cv_time_bits64" >&6; }
> > + if test "x$libgfor_cv_time_bits64" = xyes; then
> > +
> > +$as_echo "#define _TIME_BITS 64" >>confdefs.h
> > +
> > + fi
> > +
> > +
> > # Types
> > ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t"
> > "$ac_includes_default"
> > if test "x$ac_cv_type_off_t" = xyes; then :
> > diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
> > index c50112df91c..95d986f1308 100644
> > --- a/libgfortran/configure.ac
> > +++ b/libgfortran/configure.ac
> > @@ -287,6 +287,7 @@ AC_SUBST(extra_ldflags_libgfortran)
> > LIBGFOR_WORKING_GFORTRAN
> >
> > AC_SYS_LARGEFILE
> > +LIBGFOR_CHECK_TIME_BITS64
> >
> > # Types
> > AC_TYPE_OFF_T
> >
> > base-commit: ada5b8f08739b26bf76558c9d5157cbbdd16c205
> > prerequisite-patch-id: e52d299db98b0892f974152cd9fa5f6859fec5b7
> > prerequisite-patch-id: 39da6ec3264bae454fa504f127cd5b80a0662f04
> > prerequisite-patch-id: 6d6c263a964425334ad8c2edd4dd89dcbff44bfe
> > prerequisite-patch-id: 9a12a1706cbdff1edf8959682cd3cf9d900cd8f1
> > prerequisite-patch-id: b24057443c46d6979436cce479836178b19355de
> > prerequisite-patch-id: d61bf2c4249ecd3d9da5eeda002d332ed3a8b4fd
> > prerequisite-patch-id: 59cbeca60f782f48f945bc532c2235a50de6f0e5
> > prerequisite-patch-id: 8eddd3172e2007d0fc591124a56b372dfe83e683
> > prerequisite-patch-id: 862842dd3742066d039f66ffe9528bc490308c50
> > prerequisite-patch-id: e413d39d9af45f25483eaf229cf883c771444fbb
> > prerequisite-patch-id: 2faef186ad1d816bb104d89638bc4cec6d863a46
> > prerequisite-patch-id: b32cceb111f4f57798e4b1d58822281e7bbaf25e
> > prerequisite-patch-id: 08ff1c06921c5e253d911128be3a8ebb76137d3c
> > prerequisite-patch-id: 72aa7ba47bd81909871a9e1a2e9de14f2cf42174
> > prerequisite-patch-id: 2ce10434bf0a7ab22e27ff177073e10b4b7d0d72
> > prerequisite-patch-id: 68776813e47d3d411bef2f4229a589711887ca6c
> > prerequisite-patch-id: e286b2e30887f3f43a3458c7c9b3f8c8b513a91b
> > prerequisite-patch-id: dc07b9957107f8b453a87ad64fd8477ae26e370c
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri; (HRB 36809, AG Nuernberg)