master 5249f84d8b6 1/2: Update from Gnulib by running admin/merge-gnulib

Paul Eggert <[email protected]> Fri, 17 Jul 2026 17:09:28 -0400 (EDT)
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: master
commit 5249f84d8b6832a5aa27ac06588c1a1e504d4cf5
Author: Paul Eggert <[email protected]>
Commit: Paul Eggert <[email protected]>

    Update from Gnulib by running admin/merge-gnulib
---
 doc/misc/texinfo.tex    | 41 +++++++++++++++++++++++++++++---------
 lib/faccessat.c         | 24 ++++++++++++----------
 lib/fchmodat.c          | 48 +++++++++++++++++++++++++++++++-------------
 lib/fstatat.c           | 17 ++++++++++++----
 lib/getopt-pfx-ext.h    |  1 +
 lib/getopt1.c           | 12 +++++++++--
 lib/gnulib.mk.in        |  1 +
 lib/intprops-internal.h |  2 +-
 lib/md5-stream.c        |  6 +++++-
 lib/mini-gmp.c          | 52 ++++++++++++++++++++++++++++++++++--------------
 lib/mini-gmp.h          |  5 ++++-
 lib/signal.in.h         |  2 +-
 lib/stat-time.h         |  2 +-
 lib/stdbit.in.h         |  6 +++++-
 lib/stdlib.in.h         |  3 ++-
 lib/string.in.h         | 12 ++++++++---
 lib/sys_stat.in.h       | 28 +++++++++++++-------------
 lib/unistd.in.h         | 32 ++++++++++++++---------------
 m4/fcntl_h.m4           |  4 ++--
 m4/fstatat.m4           | 53 +++++++++++++++++++++++++++++++++++++++++--------
 m4/manywarnings.m4      | 49 ++++++++++++++++++++++++---------------------
 21 files changed, 273 insertions(+), 127 deletions(-)

diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index 54c2f3e7831..7187edf08e7 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -3,9 +3,9 @@
 % Load plain if necessary, i.e., if running under initex.
 \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
 %
-\def\texinfoversion{2026-04-26.12}
+\def\texinfoversion{2026-07-04.10}
 %
-% Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc.
+% Copyright 1985, 1986, 1988, 1990-2026 Free Software Foundation, Inc.
 %
 % This texinfo.tex file is free software: you can redistribute it and/or
 % modify it under the terms of the GNU General Public License as
@@ -765,22 +765,24 @@ where each line of input produces a line of output.}
 
 % @include FILE -- \input text of FILE.
 %
-\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\include{\tracingmacros=1\parseargusing\filenamecatcodes\includezzz}
 \def\includezzz#1{%
   \pushthisfilestack
   \def\thisfile{#1}%
+  \includecheckspace\thisfile
   {%
     \makevalueexpandable  % we want to expand any @value in FILE.
     \turnoffactive        % and allow special characters in the expansion
     \indexnofonts         % Allow `@@' and other weird things in file names.
     \wlog{texinfo.tex: doing @include of #1^^J}%
-    \edef\temp{\noexpand\input #1 }%
+    \edef\temp{\noexpand\input \thisfile }%
     %
     % This trickery is to read FILE outside of a group, in case it makes
     % definitions, etc.
     \expandafter
   }\temp
   \popthisfilestack
+  \def\thisfile{#1}% for @thisfile command
 }
 \def\filenamecatcodes{%
   \catcode`\\=\other
@@ -796,6 +798,21 @@ where each line of input produces a line of output.}
   \catcode`\'=\other
 }
 
+% \includecheckspace\FILENAME - if there is a space in the expansion of
+% \FILENAME, wrap the expansion in braces
+\def\includecheckspace#1{%
+  \expandafter\includecheckspacezz\expandafter#1#1 \includecheckspacezz}
+
+\def\includecheckspacezz#1#2 #3\includecheckspacezz{%
+  \def\tmp{#3}%
+  \ifx\tmp\empty
+    % no space in the file name
+  \else
+    % there is a space in the file name
+    \edef#1{{#1}}%
+  \fi
+}
+
 \def\pushthisfilestack{%
   \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
 }
@@ -5359,7 +5376,7 @@ $$%
 
 % \checksortas\segment
 % Call \indexwritesortas if a @sortas command appears in the segment
-\def\checksortas#1{
+\def\checksortas#1{%
   \let\sortas\relax
   \expandafter\checksortasx#1\relax\sortas{}\sortas
 }
@@ -5372,7 +5389,7 @@ $$%
 
 % \checkseealso\segment
 % Call \indexwriteseealso if a @seealso command appears in the segment
-\def\checkseealso#1{
+\def\checkseealso#1{%
   \let\seealso\relax
   \expandafter\checkseealsox#1\relax\seealso{}\seealso
 }
@@ -5385,7 +5402,7 @@ $$%
 
 % \checkseeentry\segment
 % Call \indexwriteseeentry if a @seeentry command appears in the segment
-\def\checkseeentry#1{
+\def\checkseeentry#1{%
   \let\seeentry\relax
   \expandafter\checkseeentryx#1\relax\seeentry{}\seeentry
 }
@@ -5798,9 +5815,9 @@ might help (with 'rm \jobname.?? \jobname.??s')%
   % The glue before the bonus allows a little bit of space at the
   % bottom of a column to reduce an increase in inter-line spacing.
   \nobreak
-  \vskip 0pt plus 5\baselineskip
+  \vskip 0pt plus 4\baselineskip
   \penalty -300
-  \vskip 0pt plus -5\baselineskip
+  \vskip 0pt plus -4\baselineskip
   %
   % Typeset the initial.  Making this add up to a whole number of
   % baselineskips increases the chance of the dots lining up from column
@@ -11010,6 +11027,12 @@ directory should work if nowhere else does.}
   \expandafter\gdef\UTFviiiTmp{#2}%
 }
 
+% Used in translation files, e.g. in txi-is.tex:
+%   \DefineSortKey{00DE}{{\string\idxsort{1}{\string\TH{}}}} % Þ
+% We provide a definition here in case the sequence shows up in sorted
+% index files.
+\def\idxsort#1#2{#2}
+
 % this could be used as follows
 %\DefineSortKey{00F1}{nzzz} % n tilde - sort between n and o
 %\DefineSortKey{00D1}{Nzzz} % N tilde - sort between n and o
diff --git a/lib/faccessat.c b/lib/faccessat.c
index ee0205e3972..c1463aa70ea 100644
--- a/lib/faccessat.c
+++ b/lib/faccessat.c
@@ -53,21 +53,25 @@ orig_faccessat (int fd, char const *name, int mode, int flag)
 #if HAVE_FACCESSAT
 
 int
-rpl_faccessat (int fd, char const *file, int mode, int flag)
+rpl_faccessat (int fd, char const *file, int mode, int flags)
 {
-  int result = orig_faccessat (fd, file, mode, flag);
+  int result = orig_faccessat (fd, file, mode, flags);
 
-  if (file[strlen (file) - 1] == '/')
+  if (file)
     {
-      struct stat st;
-      int ret = fstatat (fd, file, &st, 0);
-      if (ret == 0 && !S_ISDIR (st.st_mode))
+      size_t len = strlen (file);
+      if (len && file[len - 1] == '/')
         {
-          errno = ENOTDIR;
-          return -1;
+          struct stat st;
+          int ret = fstatat (fd, file, &st, 0);
+          if (ret == 0 && !S_ISDIR (st.st_mode))
+            {
+              errno = ENOTDIR;
+              return -1;
+            }
+          if (result == 0)
+            result = ret;
         }
-      if (result == 0)
-        result = ret;
     }
 
   return result;
diff --git a/lib/fchmodat.c b/lib/fchmodat.c
index 9ac951ce68d..fa225901533 100644
--- a/lib/fchmodat.c
+++ b/lib/fchmodat.c
@@ -48,18 +48,32 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags)
 
 #include "issymlinkat.h"
 
+#ifndef AT_EMPTY_PATH
+# define AT_EMPTY_PATH 0
+#endif
+
 /* Invoke chmod or lchmod on FILE, using mode MODE, in the directory
    open on descriptor FD.  If possible, do it without changing the
    working directory.  Otherwise, resort to using save_cwd/fchdir,
    then (chmod|lchmod)/restore_cwd.  If either the save_cwd or the
    restore_cwd fails, then give a diagnostic and exit nonzero.
-   Note that an attempt to use a FLAG value of AT_SYMLINK_NOFOLLOW
-   on a system without lchmod support causes this function to fail.  */
+   Fail if FLAGS contains AT_SYMLINK_NOFOLLOW on a system lacking
+   lchmod support.  */
 
 #if HAVE_FCHMODAT
 int
 fchmodat (int dir, char const *file, mode_t mode, int flags)
 {
+  if (file && *file)
+    flags &= ~AT_EMPTY_PATH;
+  else if (! (flags & AT_EMPTY_PATH))
+    {
+      errno = ENOENT;
+      return -1;
+    }
+  else if (! (flags & AT_SYMLINK_NOFOLLOW) && 0 <= dir)
+    return fchmod (dir, mode);
+
 # if HAVE_NEARLY_WORKING_FCHMODAT
   /* Correct the trailing slash handling.  */
   size_t len = strlen (file);
@@ -77,17 +91,21 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
 # endif
 
 # if NEED_FCHMODAT_NONSYMLINK_FIX
-  if (flags == AT_SYMLINK_NOFOLLOW)
+  if ((flags & ~AT_EMPTY_PATH) == AT_SYMLINK_NOFOLLOW)
     {
 #  if HAVE_READLINKAT
 #   ifdef O_PATH
-      /* Open a file descriptor with O_NOFOLLOW, to make sure we don't
-         follow symbolic links, if /proc is mounted.  O_PATH is used to
-         avoid a failure if the file is not readable.
-         Cf. <https://sourceware.org/PR14578>  */
-      int fd = openat (dir, file, O_PATH | O_NOFOLLOW | O_CLOEXEC);
-      if (fd < 0)
-        return fd;
+      int fd;
+      if (flags & AT_EMPTY_PATH)
+        fd = dir;
+      else
+        {
+          /* Open with O_NOFOLLOW, so we don't follow symlinks.
+             See <https://sourceware.org/PR14578>.  */
+          fd = openat (dir, file, O_PATH | O_NOFOLLOW | O_CLOEXEC);
+          if (fd < 0)
+            return fd;
+        }
 
       int err;
       {
@@ -105,7 +123,8 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
           err = errno == ENOENT ? -1 : errno;
       }
 
-      close (fd);
+      if (! (flags & AT_EMPTY_PATH))
+        close (fd);
 
       errno = err;
       if (0 <= err)
@@ -114,15 +133,16 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
 
       /* O_PATH + /proc is not supported.  */
 
-      if (issymlinkat (dir, file) > 0)
+      if (issymlinkat (dir, file ? file : "") > 0)
         {
           errno = EOPNOTSUPP;
           return -1;
         }
 #  endif
 
-      /* Fall back on orig_fchmodat with no flags, despite a possible race.  */
-      flags = 0;
+      /* Fall back on orig_fchmodat without AT_SYMLINK_NOFOLLOW,
+         despite a possible race.  */
+      flags &= ~AT_SYMLINK_NOFOLLOW;
     }
 # endif
 
diff --git a/lib/fstatat.c b/lib/fstatat.c
index 8d26e44501a..6b0c564a210 100644
--- a/lib/fstatat.c
+++ b/lib/fstatat.c
@@ -46,6 +46,10 @@ orig_fstatat (int fd, char const *filename, struct stat *buf, int flags)
 #include <stdlib.h>
 #include <string.h>
 
+#ifndef AT_EMPTY_PATH
+# define AT_EMPTY_PATH 0
+#endif
+
 #if HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG
 
 # ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK
@@ -68,14 +72,19 @@ normal_fstatat (int fd, char const *file, struct stat *st, int flag)
    Work around this bug if FSTATAT_AT_FDCWD_0_BROKEN is nonzero.  */
 
 int
-rpl_fstatat (int fd, char const *file, struct stat *st, int flag)
+rpl_fstatat (int fd, char const *file, struct stat *st, int flags)
 {
-  int result = normal_fstatat (fd, file, st, flag);
+  /* Implement Linux kernel 6.11+ behavior on platforms that have
+     AT_EMPTY_PATH but do not support it on null pointers.  */
+  if (flags & AT_EMPTY_PATH && !file)
+    file = "";
+
+  int result = normal_fstatat (fd, file, st, flags);
   if (LSTAT_FOLLOWS_SLASHED_SYMLINK || result != 0)
     return result;
 
   size_t len = strlen (file);
-  if (flag & AT_SYMLINK_NOFOLLOW)
+  if (flags & AT_SYMLINK_NOFOLLOW)
     {
       /* Fix lstat behavior.  */
       if (file[len - 1] != '/' || S_ISDIR (st->st_mode))
@@ -85,7 +94,7 @@ rpl_fstatat (int fd, char const *file, struct stat *st, int flag)
           errno = ENOTDIR;
           return -1;
         }
-      result = normal_fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW);
+      result = normal_fstatat (fd, file, st, flags & ~AT_SYMLINK_NOFOLLOW);
     }
   /* Fix stat behavior.  */
   if (result == 0 && !S_ISDIR (st->st_mode) && file[len - 1] == '/')
diff --git a/lib/getopt-pfx-ext.h b/lib/getopt-pfx-ext.h
index db2e27f36c3..189598a125b 100644
--- a/lib/getopt-pfx-ext.h
+++ b/lib/getopt-pfx-ext.h
@@ -58,6 +58,7 @@
 #ifndef __getopt_argv_const
 # if defined __GETOPT_PREFIX
 #  define __getopt_argv_const /* empty */
+#  define __getopt_argv_const_is_empty 1
 # else
 #  define __getopt_argv_const const
 # endif
diff --git a/lib/getopt1.c b/lib/getopt1.c
index a5f9988828b..7a5ae1cad07 100644
--- a/lib/getopt1.c
+++ b/lib/getopt1.c
@@ -24,11 +24,19 @@
 #include <getopt.h>
 #include "getopt_int.h"
 
+/* Convert char *__getopt_argv_const * to char ** without provoking
+   gcc -Wuseless-cast when __getopt_argv_gconst is empty.  */
+#ifdef __getopt_argv_const_is_empty
+# define ARGV_CAST(argv) (argv)
+#else
+# define ARGV_CAST(argv) ((char **) (argv))
+#endif
+
 int
 getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
 	     const struct option *long_options, int *opt_index)
 {
-  return _getopt_internal (argc, (char **) argv, options, long_options,
+  return _getopt_internal (argc, ARGV_CAST (argv), options, long_options,
 			   opt_index, 0, 0);
 }
 
@@ -51,7 +59,7 @@ getopt_long_only (int argc, char *__getopt_argv_const *argv,
 		  const char *options,
 		  const struct option *long_options, int *opt_index)
 {
-  return _getopt_internal (argc, (char **) argv, options, long_options,
+  return _getopt_internal (argc, ARGV_CAST (argv), options, long_options,
 			   opt_index, 1, 0);
 }
 
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 0605164636d..c0eac711139 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -265,6 +265,7 @@ DBUS_OBJ = @DBUS_OBJ@
 DEFS = @DEFS@
 DESLIB = @DESLIB@
 DIR_HAS_FD_MEMBER = @DIR_HAS_FD_MEMBER@
+DOCLANGS = @DOCLANGS@
 DOCMISC_W32 = @DOCMISC_W32@
 DUMPING = @DUMPING@
 DYNAMIC_LIB_SECONDARY_SUFFIX = @DYNAMIC_LIB_SECONDARY_SUFFIX@
diff --git a/lib/intprops-internal.h b/lib/intprops-internal.h
index 1fb3b799011..4055173dc84 100644
--- a/lib/intprops-internal.h
+++ b/lib/intprops-internal.h
@@ -106,7 +106,7 @@
      || (defined __clang_major__ && 4 <= __clang_major__) \
      || (defined __IBMC__ && 1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
      || (defined __SUNPRO_C && 0x5110 <= __SUNPRO_C && !__STDC__) \
-     || (defined _MSC_VER && 1939 <= _MSC_VER))
+     || (defined _MSC_VER && 1939 <= _MSC_VER && !defined __cplusplus))
 # define _GL_HAVE___TYPEOF__ 1
 #else
 # define _GL_HAVE___TYPEOF__ 0
diff --git a/lib/md5-stream.c b/lib/md5-stream.c
index ffe077f52ab..a406d17b53c 100644
--- a/lib/md5-stream.c
+++ b/lib/md5-stream.c
@@ -30,7 +30,9 @@
 # include "unlocked-io.h"
 #endif
 
-#include "af_alg.h"
+#if GNULIB_AF_ALG
+# include "af_alg.h"
+#endif
 
 #ifdef _LIBC
 # include <endian.h>
@@ -57,11 +59,13 @@
 int
 md5_stream (FILE *stream, void *resblock)
 {
+#if GNULIB_AF_ALG
   switch (afalg_stream (stream, "md5", resblock, MD5_DIGEST_SIZE))
     {
     case 0: return 0;
     case -EIO: return 1;
     }
+#endif
 
   char *buffer = malloc (BLOCKSIZE);
   if (!buffer)
diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c
index 9f3812b31bd..87cc12aa0fd 100644
--- a/lib/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -3,7 +3,7 @@
    Contributed to the GNU project by Niels Möller
    Additional functionalities and improvements by Marco Bodrato.
 
-Copyright 1991-1997, 1999-2022 Free Software Foundation, Inc.
+Copyright 1991-1997, 1999-2026 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -2832,10 +2832,10 @@ mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v)
     mpz_swap (tu, tv);
 
   tu->_mp_size = mpn_gcd (tu->_mp_d, tu->_mp_d, tu->_mp_size, tv->_mp_d, tv->_mp_size);
-  mpz_mul_2exp (g, tu, gz);
+  mpz_clear (tv);
 
+  mpz_mul_2exp (g, tu, gz);
   mpz_clear (tu);
-  mpz_clear (tv);
 }
 
 void
@@ -2969,6 +2969,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
   else
     mpz_setbit (t0, uz);
 
+  mpz_clear (tu);
   /* Now tv = odd part of gcd, and -s0 and t0 are corresponding
      cofactors. */
 
@@ -3005,13 +3006,19 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
      the one with smallest corresponding t (this asymmetric condition
      is needed to prefer s = 0, |t| = 1 when g = |a| = |b|). */
   mpz_add (s1, s0, s1);
-  mpz_sub (t1, t0, t1);
   cmp = mpz_cmpabs (s0, s1);
-  if (cmp > 0 || (cmp == 0 && mpz_cmpabs (t0, t1) > 0))
+  if (cmp >= 0)
     {
+      mpz_sub (t1, t0, t1);
+      if (cmp > 0 || mpz_cmpabs (t0, t1) > 0)
+      {
       mpz_swap (s0, s1);
       mpz_swap (t0, t1);
+      }
     }
+  mpz_clear (s1);
+  mpz_clear (t1);
+
   if (u->_mp_size < 0)
     mpz_neg (s0, s0);
   if (v->_mp_size < 0)
@@ -3023,12 +3030,9 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
   if (t)
     mpz_swap (t, t0);
 
-  mpz_clear (tu);
   mpz_clear (tv);
   mpz_clear (s0);
-  mpz_clear (s1);
   mpz_clear (t0);
-  mpz_clear (t1);
 }
 
 void
@@ -3081,6 +3085,7 @@ mpz_invert (mpz_t r, const mpz_t u, const mpz_t m)
 
   mpz_gcdext (g, tr, NULL, u, m);
   invertible = (mpz_cmp_ui (g, 1) == 0);
+  mpz_clear (g);
 
   if (invertible)
     {
@@ -3094,7 +3099,6 @@ mpz_invert (mpz_t r, const mpz_t u, const mpz_t m)
       mpz_swap (r, tr);
     }
 
-  mpz_clear (g);
   mpz_clear (tr);
   return invertible;
 }
@@ -3222,6 +3226,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
 	}
       while (bit > 0);
     }
+  mpz_clear (base);
 
   /* Final reduction */
   if (tr->_mp_size >= mn)
@@ -3235,7 +3240,6 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
 
   mpz_swap (r, tr);
   mpz_clear (tr);
-  mpz_clear (base);
 }
 
 void
@@ -3271,9 +3275,8 @@ mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
   }
 
   mpz_init (u);
-  mpz_init (t);
   bc = (mpz_sizeinbase (y, 2) - 1) / z + 1;
-  mpz_setbit (t, bc);
+  mpz_init_setbit (t, bc);
 
   if (z == 2) /* simplify sqrt loop: z-1 == 1 */
     do {
@@ -3339,12 +3342,23 @@ mpz_sqrt (mpz_t s, const mpz_t u)
 }
 
 int
-mpz_perfect_square_p (const mpz_t u)
+mpz_perfect_square_root (mpz_t r, const mpz_t u)
 {
   if (u->_mp_size <= 0)
-    return (u->_mp_size == 0);
+    {
+      int ret = u->_mp_size == 0;
+      if (r != NULL)
+	r->_mp_size = 0;
+      return ret;
+    }
   else
-    return mpz_root (NULL, u, 2);
+    return mpz_root (r, u, 2);
+}
+
+int
+mpz_perfect_square_p (const mpz_t u)
+{
+  return mpz_perfect_square_root (NULL, u);
 }
 
 int
@@ -3844,6 +3858,14 @@ mpz_combit (mpz_t d, mp_bitcnt_t bit_index)
     mpz_abs_add_bit (d, bit_index);
 }
 
+void
+mpz_init_setbit (mpz_t r, mp_bitcnt_t b)
+{
+  mpz_init (r);
+  /* mpz_setbit (r, b); */
+  mpz_abs_add_bit (r, b);
+}
+
 void
 mpz_com (mpz_t r, const mpz_t u)
 {
diff --git a/lib/mini-gmp.h b/lib/mini-gmp.h
index f28cb360ce1..eb7c3e86271 100644
--- a/lib/mini-gmp.h
+++ b/lib/mini-gmp.h
@@ -1,6 +1,7 @@
 /* mini-gmp, a minimalistic implementation of a GNU GMP subset.
 
-Copyright 2011-2015, 2017, 2019-2021 Free Software Foundation, Inc.
+Copyright 2011-2015, 2017, 2019-2021, 2024, 2026 Free Software
+Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -211,6 +212,7 @@ int mpz_invert (mpz_t, const mpz_t, const mpz_t);
 
 void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t);
 void mpz_sqrt (mpz_t, const mpz_t);
+int mpz_perfect_square_root (mpz_t, const mpz_t);
 int mpz_perfect_square_p (const mpz_t);
 
 void mpz_pow_ui (mpz_t, const mpz_t, unsigned long);
@@ -272,6 +274,7 @@ void mpz_set_d (mpz_t, double);
 void mpz_init_set_si (mpz_t, signed long int);
 void mpz_init_set_ui (mpz_t, unsigned long int);
 void mpz_init_set (mpz_t, const mpz_t);
+void mpz_init_setbit (mpz_t, mp_bitcnt_t);
 void mpz_init_set_d (mpz_t, double);
 
 size_t mpz_sizeinbase (const mpz_t, int);
diff --git a/lib/signal.in.h b/lib/signal.in.h
index 9e140ca5e83..236ec7a83c9 100644
--- a/lib/signal.in.h
+++ b/lib/signal.in.h
@@ -200,7 +200,7 @@ _GL_CXXALIAS_RPL (pthread_sigmask, int,
                    const sigset_t *restrict new_mask,
                    sigset_t *restrict old_mask));
 # else
-#  if !(@HAVE_PTHREAD_SIGMASK@ || defined pthread_sigmask)
+#  if !@HAVE_PTHREAD_SIGMASK@
 _GL_FUNCDECL_SYS (pthread_sigmask, int,
                   (int how,
                    const sigset_t *restrict new_mask,
diff --git a/lib/stat-time.h b/lib/stat-time.h
index 461a0c88b93..37b7ec4ee8d 100644
--- a/lib/stat-time.h
+++ b/lib/stat-time.h
@@ -221,7 +221,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
    in *ST, if this platform suffers from a macOS and Solaris bug where
    tv_nsec might be negative.  Return the adjusted RESULT, setting
    errno to EOVERFLOW if normalization overflowed.  This function
-   is intended to be private to this .h file.  */
+   is intended to be private to Gnulib.  */
 _GL_STAT_TIME_INLINE int
 stat_time_normalize (int result, _GL_UNUSED struct stat *st)
 {
diff --git a/lib/stdbit.in.h b/lib/stdbit.in.h
index 92749487fa8..d9a873a43aa 100644
--- a/lib/stdbit.in.h
+++ b/lib/stdbit.in.h
@@ -26,6 +26,10 @@
 
 /* The include_next requires a split double-inclusion guard.  */
 #if @HAVE_STDBIT_H@
+/* The FreeBSD 15.1 <stdbit.h> uses the _Bool type.  */
+# if defined __FreeBSD__ && defined __cplusplus
+#  define _Bool bool
+# endif
 # @INCLUDE_NEXT@ @NEXT_STDBIT_H@
 #endif
 
@@ -175,7 +179,7 @@ _GL_INLINE_HEADER_BEGIN
      || (defined __clang_major__ && 4 <= __clang_major__) \
      || (defined __IBMC__ && 1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
      || (defined __SUNPRO_C && 0x5110 <= __SUNPRO_C && !__STDC__) \
-     || (defined _MSC_VER && 1939 <= _MSC_VER))
+     || (defined _MSC_VER && 1939 <= _MSC_VER && !defined __cplusplus))
 # define _GL_STDBIT_TYPEOF_CAST(a, b) ((__typeof__ (a)) (b))
 #elif 202311 <= __STDC_VERSION__
 # define _GL_STDBIT_TYPEOF_CAST(a, b) ((typeof (a)) (b))
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 3c2004611fe..6f63c879698 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -103,7 +103,8 @@ struct random_data
 # endif
 #endif
 
-#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_MKOSTEMP@ || @GNULIB_MKOSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !(defined _WIN32 && ! defined __CYGWIN__)
+#if (@GNULIB_MKDTEMP@ || @GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_MKOSTEMP@ || @GNULIB_MKOSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !(defined _WIN32 && ! defined __CYGWIN__)
+/* On macOS 26, only <unistd.h> declares mkdtemp.  */
 /* On Mac OS X 10.3, only <unistd.h> declares mkstemp.  */
 /* On Mac OS X 10.5, only <unistd.h> declares mkstemps.  */
 /* On Mac OS X 10.13, only <unistd.h> declares mkostemp and mkostemps.  */
diff --git a/lib/string.in.h b/lib/string.in.h
index 1c46c65f60d..eb22a912c34 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -1647,15 +1647,21 @@ _GL_EXTERN_C bool mbs_endswith (const char *string, const char *suffix)
 
 /* Map any int, typically from errno, into an error message.  */
 #if @GNULIB_STRERROR@
+/* The return type 'const char *' serves the purpose of producing warnings
+   for invalid uses of the value returned from this function.  */
 # if @REPLACE_STRERROR@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef strerror
 #   define strerror rpl_strerror
+#   define GNULIB_defined_strerror 1
 #  endif
-_GL_FUNCDECL_RPL (strerror, char *, (int), );
-_GL_CXXALIAS_RPL (strerror, char *, (int));
+_GL_FUNCDECL_RPL (strerror, const char *, (int), );
+_GL_CXXALIAS_RPL (strerror, const char *, (int));
 # else
-_GL_CXXALIAS_SYS (strerror, char *, (int));
+_GL_CXXALIAS_SYS_CAST (strerror, const char *, (int));
+#  if !defined strerror && !defined __cplusplus
+#   define strerror(...) ((const char *) strerror (__VA_ARGS__))
+#  endif
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (strerror);
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index deed21cdf39..567dffa6209 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -480,18 +480,18 @@ _GL_CXXALIASWARN (chmod);
 #   define fchmodat rpl_fchmodat
 #  endif
 _GL_FUNCDECL_RPL (fchmodat, int,
-                  (int fd, char const *file, mode_t mode, int flag),
-                  _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD);
+                  (int fd, char const *file, mode_t mode, int flags),
+                  _GL_ATTRIBUTE_NODISCARD);
 _GL_CXXALIAS_RPL (fchmodat, int,
-                  (int fd, char const *file, mode_t mode, int flag));
+                  (int fd, char const *file, mode_t mode, int flags));
 # else
 #  if !@HAVE_FCHMODAT@
 _GL_FUNCDECL_SYS (fchmodat, int,
-                  (int fd, char const *file, mode_t mode, int flag),
-                  _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD);
+                  (int fd, char const *file, mode_t mode, int flags),
+                  _GL_ATTRIBUTE_NODISCARD);
 #  endif
 _GL_CXXALIAS_SYS (fchmodat, int,
-                  (int fd, char const *file, mode_t mode, int flag));
+                  (int fd, char const *file, mode_t mode, int flags));
 # endif
 _GL_CXXALIASWARN (fchmodat);
 #elif defined GNULIB_POSIXCHECK
@@ -542,7 +542,7 @@ _GL_WARN_ON_USE (fstat, "fstat has portability problems - "
 _GL_FUNCDECL_RPL (fstatat, int,
                   (int fd, char const *restrict name, struct stat *restrict st,
                    int flags),
-                  _GL_ARG_NONNULL ((2, 3)));
+                  _GL_ARG_NONNULL ((3)));
 _GL_CXXALIAS_RPL (fstatat, int,
                   (int fd, char const *restrict name, struct stat *restrict st,
                    int flags));
@@ -551,7 +551,7 @@ _GL_CXXALIAS_RPL (fstatat, int,
 _GL_FUNCDECL_SYS (fstatat, int,
                   (int fd, char const *restrict name, struct stat *restrict st,
                    int flags),
-                  _GL_ARG_NONNULL ((2, 3)));
+                  _GL_ARG_NONNULL ((3)));
 #  endif
 _GL_CXXALIAS_SYS (fstatat, int,
                   (int fd, char const *restrict name, struct stat *restrict st,
@@ -966,18 +966,18 @@ _GL_CXXALIASWARN (umask);
 #   define utimensat rpl_utimensat
 #  endif
 _GL_FUNCDECL_RPL (utimensat, int, (int fd, char const *name,
-                                   struct timespec const times[2], int flag),
-                                  _GL_ARG_NONNULL ((2)));
+                                   struct timespec const times[2], int flags),
+                  );
 _GL_CXXALIAS_RPL (utimensat, int, (int fd, char const *name,
-                                   struct timespec const times[2], int flag));
+                                   struct timespec const times[2], int flags));
 # else
 #  if !@HAVE_UTIMENSAT@
 _GL_FUNCDECL_SYS (utimensat, int, (int fd, char const *name,
-                                   struct timespec const times[2], int flag),
-                                  _GL_ARG_NONNULL ((2)));
+                                   struct timespec const times[2], int flags),
+                  );
 #  endif
 _GL_CXXALIAS_SYS (utimensat, int, (int fd, char const *name,
-                                   struct timespec const times[2], int flag));
+                                   struct timespec const times[2], int flags));
 # endif
 # if __GLIBC__ >= 2 && @HAVE_UTIMENSAT@
 _GL_CXXALIASWARN (utimensat);
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index f7e4450cede..8f40c19e2a1 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -930,18 +930,18 @@ _GL_CXXALIASWARN (execvpe);
 #   define faccessat rpl_faccessat
 #  endif
 _GL_FUNCDECL_RPL (faccessat, int,
-                  (int fd, char const *name, int mode, int flag),
-                  _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD);
+                  (int fd, char const *name, int mode, int flags),
+                  _GL_ATTRIBUTE_NODISCARD);
 _GL_CXXALIAS_RPL (faccessat, int,
-                  (int fd, char const *name, int mode, int flag));
+                  (int fd, char const *name, int mode, int flags));
 # else
 #  if !@HAVE_FACCESSAT@
 _GL_FUNCDECL_SYS (faccessat, int,
-                  (int fd, char const *file, int mode, int flag),
-                  _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD);
+                  (int fd, char const *file, int mode, int flags),
+                  _GL_ATTRIBUTE_NODISCARD);
 #  endif
 _GL_CXXALIAS_SYS (faccessat, int,
-                  (int fd, char const *file, int mode, int flag));
+                  (int fd, char const *file, int mode, int flags));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (faccessat);
@@ -997,18 +997,18 @@ _GL_WARN_ON_USE (fchdir, "fchdir is unportable - "
 #   define fchownat rpl_fchownat
 #  endif
 _GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file,
-                                  uid_t owner, gid_t group, int flag),
-                                 _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD);
+                                  uid_t owner, gid_t group, int flags),
+                  _GL_ATTRIBUTE_NODISCARD);
 _GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file,
-                                  uid_t owner, gid_t group, int flag));
+                                  uid_t owner, gid_t group, int flags));
 # else
 #  if !@HAVE_FCHOWNAT@
 _GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file,
-                                  uid_t owner, gid_t group, int flag),
-                                 _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD);
+                                  uid_t owner, gid_t group, int flags),
+                  _GL_ATTRIBUTE_NODISCARD);
 #  endif
 _GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file,
-                                  uid_t owner, gid_t group, int flag));
+                                  uid_t owner, gid_t group, int flags));
 # endif
 _GL_CXXALIASWARN (fchownat);
 #elif defined GNULIB_POSIXCHECK
@@ -1728,21 +1728,21 @@ _GL_WARN_ON_USE (link, "link is unportable - "
 #  endif
 _GL_FUNCDECL_RPL (linkat, int,
                   (int fd1, const char *path1, int fd2, const char *path2,
-                   int flag),
+                   int flags),
                   _GL_ARG_NONNULL ((2, 4)) _GL_ATTRIBUTE_NODISCARD);
 _GL_CXXALIAS_RPL (linkat, int,
                   (int fd1, const char *path1, int fd2, const char *path2,
-                   int flag));
+                   int flags));
 # else
 #  if !@HAVE_LINKAT@
 _GL_FUNCDECL_SYS (linkat, int,
                   (int fd1, const char *path1, int fd2, const char *path2,
-                   int flag),
+                   int flags),
                   _GL_ARG_NONNULL ((2, 4)) _GL_ATTRIBUTE_NODISCARD);
 #  endif
 _GL_CXXALIAS_SYS (linkat, int,
                   (int fd1, const char *path1, int fd2, const char *path2,
-                   int flag));
+                   int flags));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (linkat);
diff --git a/m4/fcntl_h.m4 b/m4/fcntl_h.m4
index 946a0bd6320..3a5ddb22194 100644
--- a/m4/fcntl_h.m4
+++ b/m4/fcntl_h.m4
@@ -1,5 +1,5 @@
 # fcntl_h.m4
-# serial 21
+# serial 22
 dnl Copyright (C) 2006-2007, 2009-2026 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -67,7 +67,7 @@ AC_DEFUN([gl_FCNTL_H_DEFAULTS],
   dnl Assume proper GNU behavior unless another module says otherwise.
   HAVE_FCNTL=1;          AC_SUBST([HAVE_FCNTL])
   HAVE_OPENAT=1;         AC_SUBST([HAVE_OPENAT])
-  HAVE_OPENAT2=0;        AC_SUBST([HAVE_OPENAT2])
+  HAVE_OPENAT2=1;        AC_SUBST([HAVE_OPENAT2]) dnl GNU/Linux only
   REPLACE_CREAT=0;       AC_SUBST([REPLACE_CREAT])
   REPLACE_FCNTL=0;       AC_SUBST([REPLACE_FCNTL])
   REPLACE_OPEN=0;        AC_SUBST([REPLACE_OPEN])
diff --git a/m4/fstatat.m4 b/m4/fstatat.m4
index d53e8d91966..34a1638e9bf 100644
--- a/m4/fstatat.m4
+++ b/m4/fstatat.m4
@@ -1,5 +1,5 @@
 # fstatat.m4
-# serial 5
+# serial 8
 dnl Copyright (C) 2004-2026 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -45,6 +45,11 @@ AC_DEFUN([gl_FUNC_FSTATAT],
           esac
          ])
       ])
+    AS_CASE([$gl_cv_func_fstatat_zero_flag],
+      [*yes],
+        [AC_DEFINE([HAVE_WORKING_FSTATAT_ZERO_FLAG], [1],
+           [Define to 1 if fstatat (..., 0) works.
+            For example, it does not work in AIX 7.1.])])
 
     case $gl_cv_func_fstatat_zero_flag+$gl_cv_func_lstat_dereferences_slashed_symlink in
     *yes+*yes) ;;
@@ -56,12 +61,44 @@ AC_DEFUN([gl_FUNC_FSTATAT],
         REPLACE_FSTATAT=1 ;;
     esac
 
-    case $REPLACE_FSTATAT,$gl_cv_func_fstatat_zero_flag in
-      1,*yes)
-         AC_DEFINE([HAVE_WORKING_FSTATAT_ZERO_FLAG], [1],
-           [Define to 1 if fstatat (..., 0) works.
-            For example, it does not work in AIX 7.1.])
-         ;;
-    esac
+    dnl Check for the AT_EMPTY_PATH compatibility issue with null pointers
+    dnl only if not already replacing fstatat.
+    dnl There is no need to AC_DEFINE anything here, as the Gnulib
+    dnl replacement works around the compatibility bug even if the bug
+    dnl is not present, and it is not worth the trouble to tune this.
+    AS_CASE([$REPLACE_FSTATAT],
+      [0],
+        [AC_CACHE_CHECK([for no AT_EMPTY_PATH or fstatat with null file],
+           [gl_cv_func_fstatat_null_file],
+           [AC_RUN_IFELSE(
+              [AC_LANG_PROGRAM(
+                 [[#include <stddef.h>
+                   #include <fcntl.h>
+                   #include <sys/stat.h>
+                   #ifndef AT_EMPTY_PATH
+                    #define AT_EMPTY_PATH 0
+                   #endif
+                   /* Don't check via -Wnonnull, as the problem could in
+                      theory exist with compilers lacking -Wnonnull.  */
+                   #if __GLIBC__ && ! (2 < __GLIBC__ + (41 <= __GLIBC_MINOR__))
+                    #error "glibc 2.40 and earlier can fail with null file"
+                   #endif
+                 ]],
+                 [[struct stat st;
+                   if (!AT_EMPTY_PATH)
+                     return 0; /* No need to replace fstatat.  */
+                   if (fstatat (AT_FDCWD, NULL, &st, AT_EMPTY_PATH) < 0)
+                     return 1;
+                   int fd = open (".", O_RDONLY);
+                   if (fd < 0)
+                     return 1; /* Play it safe.  */
+                   return fstatat (fd, NULL, &st, AT_EMPTY_PATH) < 0;
+                 ]])],
+              [gl_cv_func_fstatat_null_file=yes],
+              [gl_cv_func_fstatat_null_file=no],
+              [gl_cv_func_fstatat_null_file="guessing no"])])
+         AS_CASE([$gl_cv_func_fstatat_null_file],
+           [*no],
+             [REPLACE_FSTATAT=1])])
   fi
 ])
diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4
index ea0442d0396..02a2211201c 100644
--- a/m4/manywarnings.m4
+++ b/m4/manywarnings.m4
@@ -1,5 +1,5 @@
 # manywarnings.m4
-# serial 35
+# serial 37
 dnl Copyright (C) 2008-2026 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -97,8 +97,8 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
   # export LC_ALL=C && comm -3 \
   #  <((sed -n 's/^  *\(-[^ 0-9][^ ]*\).*/\1/p' manywarnings.m4; \
   #     awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec) | sort) \
-  #  <((gcc --help=c,warnings && gcc --help=common,warnings) \
-  #    | sed -n 's/^  \(-[^ ]*\) .*/\1/p' | sort)
+  #  <((gcc -Q --help=c,warnings && gcc -Q --help=common,warnings) \
+  #    | sed -n '/\[ignored]$/d;s/^  \(-[^ ]*\) .*/\1/p' | sort)
 
   $1=
   for gl_manywarn_item in -fanalyzer -fstrict-flex-arrays \
@@ -133,7 +133,6 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
     -Wshadow \
     -Wstack-protector \
     -Wstrict-flex-arrays \
-    -Wstrict-overflow \
     -Wstrict-prototypes \
     -Wsuggest-attribute=cold \
     -Wsuggest-attribute=const \
@@ -145,7 +144,6 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
     -Wtrampolines \
     -Wuninitialized \
     -Wunknown-pragmas \
-    -Wunsafe-loop-optimizations \
     -Wunused-macros \
     -Wvariadic-macros \
     -Wvector-operation-performance \
@@ -171,36 +169,41 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
   AS_VAR_APPEND([$1], [' -Wvla-larger-than=4031'])
 
   # These depend on the GCC version.
-  if test -n "$GCC" && gl_gcc_version=`($CC --version) 2>/dev/null`; then
+  if test -n "$GCC" \
+     && gl_gcc_version=`($CC --version) 2>/dev/null | sed 1q`; then
     case $gl_gcc_version in
-      gcc*' ('*') '[[0-3]].* | \
-      gcc*' ('*') '4.[[0-7]].*)
+      *gcc*' ('*') '[[0-3]].* | \
+      *gcc*' ('*') '4.[[0-7]].*)
         AS_VAR_APPEND([$1], [' -fdiagnostics-show-option'])
         AS_VAR_APPEND([$1], [' -funit-at-a-time'])
-          ;;
+        ;;
     esac
     case $gl_gcc_version in
-      gcc*' ('*') '[[0-9]].*)
+      *gcc*' ('*') '[[0-9]].*)
+        # In GCC >= 10 this option is no longer needed, as it is
+        # enabled by default.
         AS_VAR_APPEND([$1], [' -fno-common'])
-          ;;
+        ;;
     esac
     case $gl_gcc_version in
-      gcc*' ('*') '?.* | gcc*' ('*') '1[[0-3]].*)
-          # In GCC < 14 the option either does not exist,
-          # or is accepted but always warns.
-          ;;
+      *gcc*' ('*') '[[0-9]].* | \
+      *gcc*' ('*') '1[[0-3]].*)
+        # In GCC < 14 the option either does not exist,
+        # or is accepted but always warns.
+        ;;
       *)
-          AS_VAR_APPEND([$1], [' -Wuseless-cast'])
-          ;;
+        AS_VAR_APPEND([$1], [' -Wuseless-cast'])
+        ;;
     esac
     case $gl_gcc_version in
-      gcc*' ('*') '?.* | gcc*' ('*') '1[[0-4]].*)
-          # In GCC < 15 the option either does not exist,
-          # or is accepted but always warns.
-          ;;
+      *gcc*' ('*') '[[0-9]].* | \
+      *gcc*' ('*') '1[[0-4]].*)
+        # In GCC < 15 the option either does not exist,
+        # or is accepted but always warns.
+        ;;
       *)
-          AS_VAR_APPEND([$1], [' -Wzero-as-null-pointer-constant'])
-          ;;
+        AS_VAR_APPEND([$1], [' -Wzero-as-null-pointer-constant'])
+        ;;
     esac
   fi