Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Paul Eggert

On 4/18/21 5:04 PM, Bruno Haible wrote:

Paul Eggert wrote:

I installed the attached instead, as this is simpler.


And I'm already starting to wonder whether testing for ptrdiff_t 
overflow was such a good idea. I installed the attached further patch to 
try to pacify GCC diagnostics about them.


If these ptrdiff_t tests turn out to be too much trouble we can always 
withdraw them.
>From 11e793833378de5a5978b296af1c0993f7305eda Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sun, 18 Apr 2021 21:18:00 -0700
Subject: [PATCH] malloc-gnu-tests: pacify -Walloc-size-larger-than
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* tests/test-malloc-gnu.c (main):
* tests/test-realloc-gnu.c (main): Hide true intentions from GCC,
to prevent diagnostics like “warning: argument 1 value
‘9223372036854775808’ exceeds maximum object size
9223372036854775807 [-Walloc-size-larger-than=]”.
---
 ChangeLog| 7 +++
 tests/test-malloc-gnu.c  | 6 +++---
 tests/test-realloc-gnu.c | 6 +++---
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2c7edd59a..0146e1594 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2021-04-18  Paul Eggert  
 
+	malloc-gnu-tests: pacify -Walloc-size-larger-than
+	* tests/test-malloc-gnu.c (main):
+	* tests/test-realloc-gnu.c (main): Hide true intentions from GCC,
+	to prevent diagnostics like “warning: argument 1 value
+	‘9223372036854775808’ exceeds maximum object size
+	9223372036854775807 [-Walloc-size-larger-than=]”.
+
 	safe-alloc: fix pointer implementation
 	The old implementation assumed that all pointers use the same
 	internal representation, but the C standard doesn’t guarantee
diff --git a/tests/test-malloc-gnu.c b/tests/test-malloc-gnu.c
index ce7e4fec2..e1dfde452 100644
--- a/tests/test-malloc-gnu.c
+++ b/tests/test-malloc-gnu.c
@@ -20,7 +20,7 @@
 #include 
 
 int
-main ()
+main (int argc, char **argv)
 {
   /* Check that malloc (0) is not a NULL pointer.  */
   char *p = malloc (0);
@@ -31,8 +31,8 @@ main ()
   /* Check that malloc (n) fails when n exceeds PTRDIFF_MAX.  */
   if (PTRDIFF_MAX < SIZE_MAX)
 {
-  size_t n = PTRDIFF_MAX, n1 = n + 1;
-  if (malloc (n1) != NULL)
+  size_t one = argc != 12345;
+  if (malloc (PTRDIFF_MAX + one) != NULL)
 return 1;
 }
 
diff --git a/tests/test-realloc-gnu.c b/tests/test-realloc-gnu.c
index 9c7344f15..b62ee6bad 100644
--- a/tests/test-realloc-gnu.c
+++ b/tests/test-realloc-gnu.c
@@ -20,7 +20,7 @@
 #include 
 
 int
-main ()
+main (int argc, char **argv)
 {
   /* Check that realloc (NULL, 0) is not a NULL pointer.  */
   char *p = realloc (NULL, 0);
@@ -31,8 +31,8 @@ main ()
  PTRDIFF_MAX.  */
   if (PTRDIFF_MAX < SIZE_MAX)
 {
-  size_t n = PTRDIFF_MAX, n1 = n + 1;
-  if (realloc (p, n1) != NULL)
+  size_t one = argc != 12345;
+  if (realloc (p, PTRDIFF_MAX + one) != NULL)
 return 1;
 }
 
-- 
2.27.0



[PATCH 4/8] xalloc: new function xreallocarray

2021-04-18 Thread Paul Eggert
This effectively replaces xnmalloc, which perhaps should be deprecated.
The name xreallocarray should be easier to remember now that
reallocarray is a standard GNU function.
* lib/xalloc.h [GNULIB_XALLOC]: Do not include xalloc-oversized.h.
(xnmalloc, xnrealloc, x2nrealloc): Simplify by using xreallocarray.
* lib/xmalloc.c (xreallocarray): New function.
* modules/xalloc (Depends-on): Add reallocarray;
remove xalloc-oversized.
---
 ChangeLog  | 10 ++
 lib/xalloc.h   | 26 ++
 lib/xmalloc.c  | 12 
 modules/xalloc |  2 +-
 4 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index aff0e87fc..857b7048f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2021-04-18  Paul Eggert  
 
+   xalloc: new function xreallocarray
+   This effectively replaces xnmalloc, which perhaps should be deprecated.
+   The name xreallocarray should be easier to remember now that
+   reallocarray is a standard GNU function.
+   * lib/xalloc.h [GNULIB_XALLOC]: Do not include xalloc-oversized.h.
+   (xnmalloc, xnrealloc, x2nrealloc): Simplify by using xreallocarray.
+   * lib/xmalloc.c (xreallocarray): New function.
+   * modules/xalloc (Depends-on): Add reallocarray;
+   remove xalloc-oversized.
+
group-member: simplify via realloc-gnu
* lib/group-member.c, modules/group-member:
Simplify similarly to backupfile.
diff --git a/lib/xalloc.h b/lib/xalloc.h
index b08ab4e07..6cd7a680c 100644
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
@@ -24,7 +24,6 @@
 #if GNULIB_XALLOC
 # include "idx.h"
 # include "intprops.h"
-# include "xalloc-oversized.h"
 #endif
 
 #ifndef _GL_INLINE_HEADER_BEGIN
@@ -62,6 +61,8 @@ void *xcalloc (size_t n, size_t s)
   _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
 void *xrealloc (void *p, size_t s)
   _GL_ATTRIBUTE_ALLOC_SIZE ((2));
+void *xreallocarray (void *p, size_t n, size_t s)
+  _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
 void *x2realloc (void *p, size_t *pn);
 void *xpalloc (void *pa, idx_t *nitems, idx_t nitems_incr_min,
ptrdiff_t nitems_max, idx_t item_size);
@@ -104,11 +105,10 @@ XALLOC_INLINE void *xnmalloc (size_t n, size_t s)
 XALLOC_INLINE void *
 xnmalloc (size_t n, size_t s)
 {
-  if (xalloc_oversized (n, s))
-xalloc_die ();
-  return xmalloc (n * s);
+  return xreallocarray (NULL, n, s);
 }
 
+/* FIXME: Deprecate this in favor of xreallocarray?  */
 /* Change the size of an allocated block of memory P to an array of N
objects each of S bytes, with error checking.  S must be nonzero.  */
 
@@ -117,9 +117,7 @@ XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s)
 XALLOC_INLINE void *
 xnrealloc (void *p, size_t n, size_t s)
 {
-  if (xalloc_oversized (n, s))
-xalloc_die ();
-  return xrealloc (p, n * s);
+  return xreallocarray (p, n, s);
 }
 
 /* If P is null, allocate a block of at least *PN such objects;
@@ -202,10 +200,7 @@ x2nrealloc (void *p, size_t *pn, size_t s)
 xalloc_die ();
 }
 
-  xalloc_count_t nbytes;
-  if (INT_MULTIPLY_WRAPV (n, s, ))
-xalloc_die ();
-  p = xrealloc (p, nbytes);
+  p = xreallocarray (p, n, s);
   *pn = n;
   return p;
 }
@@ -241,10 +236,17 @@ xrealloc (T *p, size_t s)
   return (T *) xrealloc ((void *) p, s);
 }
 
+template  inline T *
+xreallocarray (T *p, size_t n, size_t s)
+{
+  return (T *) xreallocarray ((void *) p, n, s);
+}
+
+/* FIXME: Deprecate this in favor of xreallocarray?  */
 template  inline T *
 xnrealloc (T *p, size_t n, size_t s)
 {
-  return (T *) xnrealloc ((void *) p, n, s);
+  return xreallocarray (p, n, s);
 }
 
 template  inline T *
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
index 39ce893ad..88698fade 100644
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -50,6 +50,18 @@ xrealloc (void *p, size_t n)
   return r;
 }
 
+/* Change the size of an allocated block of memory P to an array of N
+   objects each of S bytes, with error checking.  */
+
+void *
+xreallocarray (void *p, size_t n, size_t s)
+{
+  void *r = reallocarray (p, n, s);
+  if (!r && (!p || (n && s)))
+xalloc_die ();
+  return r;
+}
+
 /* If P is null, allocate a block of at least *PN bytes; otherwise,
reallocate P so that it contains more than *PN bytes.  *PN must be
nonzero unless P is null.  Set *PN to the new block's size, and
diff --git a/modules/xalloc b/modules/xalloc
index 000933e94..0dbae1c86 100644
--- a/modules/xalloc
+++ b/modules/xalloc
@@ -15,9 +15,9 @@ intprops
 malloc-gnu
 minmax
 realloc-gnu
+reallocarray
 stdint
 xalloc-die
-xalloc-oversized
 
 configure.ac:
 gl_XALLOC
-- 
2.27.0




[PATCH 6/8] safe-alloc: simplify via reallocarray

2021-04-18 Thread Paul Eggert
* lib/safe-alloc.c: Do not include xalloc-oversized.h.
(safe_alloc_alloc_n, safe_alloc_realloc_n):
Use reallocarray to check for size or ptrdiff_t overflow.
* modules/reallocarray (License): Switch from LGPL to LGPLv2+, as
this is needed for safe-alloc and anyway is more appropriate for
this library function common with BSD.
* modules/safe-alloc (Depends-on): Depend on reallocarray
rather than xalloc-oversized.
---
 ChangeLog| 10 ++
 lib/safe-alloc.c | 17 ++---
 modules/reallocarray |  2 +-
 modules/safe-alloc   |  2 +-
 4 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1d2607a0b..76d714127 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2021-04-18  Paul Eggert  
 
+   safe-alloc: simplify via reallocarray
+   * lib/safe-alloc.c: Do not include xalloc-oversized.h.
+   (safe_alloc_alloc_n, safe_alloc_realloc_n):
+   Use reallocarray to check for size or ptrdiff_t overflow.
+   * modules/reallocarray (License): Switch from LGPL to LGPLv2+, as
+   this is needed for safe-alloc and anyway is more appropriate for
+   this library function common with BSD.
+   * modules/safe-alloc (Depends-on): Depend on reallocarray
+   rather than xalloc-oversized.
+
xalloc-oversized: fix SIZE_MAX optimization bug
* lib/xalloc-oversized.h (xalloc_count_t): Remove; no longer
needed and was evidently error-prone anyway.
diff --git a/lib/safe-alloc.c b/lib/safe-alloc.c
index 45e770015..116ac4371 100644
--- a/lib/safe-alloc.c
+++ b/lib/safe-alloc.c
@@ -22,8 +22,6 @@
 /* Specification.  */
 #include "safe-alloc.h"
 
-#include "xalloc-oversized.h"
-
 #include 
 #include 
 #include 
@@ -51,16 +49,10 @@ safe_alloc_alloc_n (void *ptrptr, size_t size, size_t 
count, int zeroed)
   return 0;
 }
 
-  if (xalloc_oversized (count, size))
-{
-  errno = ENOMEM;
-  return -1;
-}
-
   if (zeroed)
 *(void **) ptrptr = calloc (count, size);
   else
-*(void **) ptrptr = malloc (count * size);
+*(void **) ptrptr = reallocarray (NULL, count, size);
 
   if (*(void **) ptrptr == NULL)
 return -1;
@@ -91,12 +83,7 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t 
count)
   *(void **) ptrptr = NULL;
   return 0;
 }
-  if (xalloc_oversized (count, size))
-{
-  errno = ENOMEM;
-  return -1;
-}
-  tmp = realloc (*(void **) ptrptr, size * count);
+  tmp = reallocarray (*(void **) ptrptr, size, count);
   if (!tmp)
 return -1;
   *(void **) ptrptr = tmp;
diff --git a/modules/reallocarray b/modules/reallocarray
index 11d32bb5f..a64c6fd2d 100644
--- a/modules/reallocarray
+++ b/modules/reallocarray
@@ -26,7 +26,7 @@ Include:
 
 
 License:
-LGPL
+LGPLv2+
 
 Maintainer:
 all
diff --git a/modules/safe-alloc b/modules/safe-alloc
index 13e78dec7..9453b49ee 100644
--- a/modules/safe-alloc
+++ b/modules/safe-alloc
@@ -7,7 +7,7 @@ lib/safe-alloc.c
 m4/safe-alloc.m4
 
 Depends-on:
-xalloc-oversized
+reallocarray
 
 configure.ac:
 gl_SAFE_ALLOC
-- 
2.27.0




[PATCH 5/8] xalloc-oversized: fix SIZE_MAX optimization bug

2021-04-18 Thread Paul Eggert
* lib/xalloc-oversized.h (xalloc_count_t): Remove; no longer
needed and was evidently error-prone anyway.
(xalloc_oversized): Omit some over-optimization that caused
SIZE_MAX to not be treated as too large (the Gnulib convention) on
unusual platforms where PTRDIFF_MAX == SIZE_MAX.  This change
should not affect typical platforms where PTRDIFF_MAX < SIZE_MAX.
When optimizing, simply use ptrdiff_t instead of xalloc_count_t.
---
 ChangeLog  |  9 +
 lib/xalloc-oversized.h | 17 ++---
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 857b7048f..1d2607a0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2021-04-18  Paul Eggert  
 
+   xalloc-oversized: fix SIZE_MAX optimization bug
+   * lib/xalloc-oversized.h (xalloc_count_t): Remove; no longer
+   needed and was evidently error-prone anyway.
+   (xalloc_oversized): Omit some over-optimization that caused
+   SIZE_MAX to not be treated as too large (the Gnulib convention) on
+   unusual platforms where PTRDIFF_MAX == SIZE_MAX.  This change
+   should not affect typical platforms where PTRDIFF_MAX < SIZE_MAX.
+   When optimizing, simply use ptrdiff_t instead of xalloc_count_t.
+
xalloc: new function xreallocarray
This effectively replaces xnmalloc, which perhaps should be deprecated.
The name xreallocarray should be easier to remember now that
diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h
index 3618c75cb..6437a5d8b 100644
--- a/lib/xalloc-oversized.h
+++ b/lib/xalloc-oversized.h
@@ -30,25 +30,20 @@
 #define __xalloc_oversized(n, s) \
   ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
 
-#if PTRDIFF_MAX < SIZE_MAX
-typedef ptrdiff_t xalloc_count_t;
-#else
-typedef size_t xalloc_count_t;
-#endif
-
 /* Return 1 if an array of N objects, each of size S, cannot exist reliably
-   because its total size in bytes exceeds MIN (PTRDIFF_MAX, SIZE_MAX).
+   because its total size in bytes exceeds MIN (PTRDIFF_MAX, SIZE_MAX - 1).
N must be nonnegative, S must be positive, and either N or S should be
of type ptrdiff_t or size_t or wider.  This is a macro, not a function,
so that it works even if an argument exceeds MAX (PTRDIFF_MAX, SIZE_MAX).  
*/
-#if 7 <= __GNUC__ && !defined __clang__
+#if 7 <= __GNUC__ && !defined __clang__ && PTRDIFF_MAX < SIZE_MAX
 # define xalloc_oversized(n, s) \
-   __builtin_mul_overflow_p (n, s, (xalloc_count_t) 1)
-#elif 5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__
+   __builtin_mul_overflow_p (n, s, (ptrdiff_t) 1)
+#elif (5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__ \
+   && PTRDIFF_MAX < SIZE_MAX)
 # define xalloc_oversized(n, s) \
(__builtin_constant_p (n) && __builtin_constant_p (s) \
 ? __xalloc_oversized (n, s) \
-: ({ xalloc_count_t __xalloc_count; \
+: ({ ptrdiff_t __xalloc_count; \
  __builtin_mul_overflow (n, s, &__xalloc_count); }))
 
 /* Other compilers use integer division; this may be slower but is
-- 
2.27.0




[PATCH 8/8] safe-alloc: fix pointer implementation

2021-04-18 Thread Paul Eggert
The old implementation assumed that all pointers use the same
internal representation, but the C standard doesn’t guarantee
this.  Use void * (pointer) not void ** (pointer-to-pointer) for
the internal functions’ API.  The internal functions now return
NULL if and only if they failed, and the macros translate that
into -1 or 0 to satisfy the existing API.
* doc/safe-alloc.texi (Safe Allocation Macros): Mention overflow.
* lib/safe-alloc.c: Major rewrite.  Now this simply
defines SAFE_ALLOC_INLINE and includes safe-alloc.h.
* lib/safe-alloc.h: Include stddef.h, not stdlib.h.
(SAFE_ALLOC_INLINE): New macro; use Gnulib inline function style.
(safe_alloc_realloc_n): New API, which passes and returns
the pointer, and which returns NULL if and only if failure occurs.
(safe_alloc_check): New function.
(ALLOC, ALLOC_N, ALLOC_N_UNINITIALIZED, REALLOC_N):
Redo using the new API for internal functions, and using calloc
which is good enough since it’s GNU-compatible now.
(FREE): Expand to an expression rather than merely to something
that needs a following ‘;’ to become a statement.
* modules/safe-alloc (Depends-on): Add calloc-gnu.
---
 ChangeLog   | 22 +++
 doc/safe-alloc.texi |  2 +
 lib/safe-alloc.c| 90 +---
 lib/safe-alloc.h| 91 +
 modules/safe-alloc  |  1 +
 5 files changed, 76 insertions(+), 130 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ede998670..2c7edd59a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
 2021-04-18  Paul Eggert  
 
+   safe-alloc: fix pointer implementation
+   The old implementation assumed that all pointers use the same
+   internal representation, but the C standard doesn’t guarantee
+   this.  Use void * (pointer) not void ** (pointer-to-pointer) for
+   the internal functions’ API.  The internal functions now return
+   NULL if and only if they failed, and the macros translate that
+   into -1 or 0 to satisfy the existing API.
+   * doc/safe-alloc.texi (Safe Allocation Macros): Mention overflow.
+   * lib/safe-alloc.c: Major rewrite.  Now this simply
+   defines SAFE_ALLOC_INLINE and includes safe-alloc.h.
+   * lib/safe-alloc.h: Include stddef.h, not stdlib.h.
+   (SAFE_ALLOC_INLINE): New macro; use Gnulib inline function style.
+   (safe_alloc_realloc_n): New API, which passes and returns
+   the pointer, and which returns NULL if and only if failure occurs.
+   (safe_alloc_check): New function.
+   (ALLOC, ALLOC_N, ALLOC_N_UNINITIALIZED, REALLOC_N):
+   Redo using the new API for internal functions, and using calloc
+   which is good enough since it’s GNU-compatible now.
+   (FREE): Expand to an expression rather than merely to something
+   that needs a following ‘;’ to become a statement.
+   * modules/safe-alloc (Depends-on): Add calloc-gnu.
+
calloc-gnu: now LGPLv2+
* modules/calloc-gnu (License): Change from GPL to LGPLv2+.
The old value was evidently a longstanding typo, and calloc
diff --git a/doc/safe-alloc.texi b/doc/safe-alloc.texi
index d40ec65b6..e896e2598 100644
--- a/doc/safe-alloc.texi
+++ b/doc/safe-alloc.texi
@@ -13,6 +13,8 @@ Some of the memory allocation mistakes that are commonly made 
are
 passing the incorrect number of bytes to @code{malloc}, especially
 when allocating an array,
 @item
+unchecked integer overflow when calculating array sizes,
+@item
 fail to check the return value of @code{malloc} and @code{realloc} for
 errors,
 @item
diff --git a/lib/safe-alloc.c b/lib/safe-alloc.c
index 116ac4371..df061f9ef 100644
--- a/lib/safe-alloc.c
+++ b/lib/safe-alloc.c
@@ -1,91 +1,3 @@
-/* safe-alloc.c: safer memory allocation
-
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 3 of the License, or any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see .  */
-
-/* Written by Daniel Berrange , 2008 */
-
 #include 
-
-/* Specification.  */
+#define SAFE_ALLOC_INLINE _GL_EXTERN_INLINE
 #include "safe-alloc.h"
-
-#include 
-#include 
-#include 
-
-
-/**
- * safe_alloc_alloc_n:
- * @ptrptr: pointer to pointer for address of allocated memory
- * @size: number of bytes to allocate
- * @count: number of elements to allocate
- *
- * Allocate an array of memory 'count' elements long,
- * each with 'size' bytes. Return the address of the
- * allocated memory in 'ptrptr'.  The newly 

[PATCH 7/8] calloc-gnu: now LGPLv2+

2021-04-18 Thread Paul Eggert
* modules/calloc-gnu (License): Change from GPL to LGPLv2+.
The old value was evidently a longstanding typo, and calloc
will be needed by LGPLv2+ modules that will want to rely
on GNU behavior.
---
 ChangeLog  | 6 ++
 modules/calloc-gnu | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 76d714127..ede998670 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2021-04-18  Paul Eggert  
 
+   calloc-gnu: now LGPLv2+
+   * modules/calloc-gnu (License): Change from GPL to LGPLv2+.
+   The old value was evidently a longstanding typo, and calloc
+   will be needed by LGPLv2+ modules that will want to rely
+   on GNU behavior.
+
safe-alloc: simplify via reallocarray
* lib/safe-alloc.c: Do not include xalloc-oversized.h.
(safe_alloc_alloc_n, safe_alloc_realloc_n):
diff --git a/modules/calloc-gnu b/modules/calloc-gnu
index 2aa2dd1c0..bbd2a4933 100644
--- a/modules/calloc-gnu
+++ b/modules/calloc-gnu
@@ -20,7 +20,7 @@ Include:
 
 
 License:
-GPL
+LGPLv2+
 
 Maintainer:
 Jim Meyering
-- 
2.27.0




[PATCH 3/8] group-member: simplify via realloc-gnu

2021-04-18 Thread Paul Eggert
* lib/group-member.c, modules/group-member:
Simplify similarly to backupfile.
---
 ChangeLog| 4 
 lib/group-member.c   | 6 ++
 modules/group-member | 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e00a5b7c8..aff0e87fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2021-04-18  Paul Eggert  
 
+   group-member: simplify via realloc-gnu
+   * lib/group-member.c, modules/group-member:
+   Simplify similarly to backupfile.
+
backupfile: simplify via realloc-gnu
* lib/backupfile.c: Do not include xalloc-oversized.h.
(numbered_backup): Simplify now that realloc will do the right
diff --git a/lib/group-member.c b/lib/group-member.c
index 17bee831b..d433f2731 100644
--- a/lib/group-member.c
+++ b/lib/group-member.c
@@ -26,7 +26,6 @@
 #include 
 
 #include "intprops.h"
-#include "xalloc-oversized.h"
 
 /* Most processes have no more than this many groups, and for these
processes we can avoid using malloc.  */
@@ -54,9 +53,8 @@ get_group_info (struct group_info *gi)
   if (n_groups < 0)
 {
   int n_group_slots = getgroups (0, NULL);
-  xalloc_count_t nbytes;
-  if (0 <= n_group_slots
-  && ! INT_MULTIPLY_WRAPV (n_group_slots, sizeof *gi->group, ))
+  size_t nbytes;
+  if (! INT_MULTIPLY_WRAPV (n_group_slots, sizeof *gi->group, ))
 {
   gi->group = malloc (nbytes);
   if (gi->group)
diff --git a/modules/group-member b/modules/group-member
index aa56ecf7e..a224d9888 100644
--- a/modules/group-member
+++ b/modules/group-member
@@ -10,7 +10,7 @@ unistd
 extensions
 getgroups[test $HAVE_GROUP_MEMBER = 0]
 intprops [test $HAVE_GROUP_MEMBER = 0]
-xalloc-oversized [test $HAVE_GROUP_MEMBER = 0]
+realloc-gnu  [test $HAVE_GROUP_MEMBER = 0]
 
 configure.ac:
 gl_FUNC_GROUP_MEMBER
-- 
2.27.0




[PATCH 2/8] backupfile: simplify via realloc-gnu

2021-04-18 Thread Paul Eggert
* lib/backupfile.c: Do not include xalloc-oversized.h.
(numbered_backup): Simplify now that realloc will do the right
thing about ptrdiff_t overflow.
* modules/backupfile (Depends-on): Add realloc-gnu;
remove xalloc-oversized.
---
 ChangeLog  | 7 +++
 lib/backupfile.c   | 3 +--
 modules/backupfile | 2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d2d12058e..e00a5b7c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2021-04-18  Paul Eggert  
 
+   backupfile: simplify via realloc-gnu
+   * lib/backupfile.c: Do not include xalloc-oversized.h.
+   (numbered_backup): Simplify now that realloc will do the right
+   thing about ptrdiff_t overflow.
+   * modules/backupfile (Depends-on): Add realloc-gnu;
+   remove xalloc-oversized.
+
safe-alloc: improve doc
* doc/safe-alloc.texi: Clarify that reallocating an array appends
uninitialized storage.  Say ‘sizeof *p’ rather than ‘sizeof(*p)’
diff --git a/lib/backupfile.c b/lib/backupfile.c
index 1e427e8de..bc03dd614 100644
--- a/lib/backupfile.c
+++ b/lib/backupfile.c
@@ -37,7 +37,6 @@
 #include "intprops.h"
 #include "opendirat.h"
 #include "renameatu.h"
-#include "xalloc-oversized.h"
 
 #ifndef _D_EXACT_NAMLEN
 # define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
@@ -271,7 +270,7 @@ numbered_backup (int dir_fd, char **buffer, size_t 
buffer_size, size_t filelen,
   size_t new_buffer_size = filelen + 2 + versionlenmax + 2;
   if (buffer_size < new_buffer_size)
 {
-  xalloc_count_t grown;
+  size_t grown;
   if (! INT_ADD_WRAPV (new_buffer_size, new_buffer_size >> 1, ))
 new_buffer_size = grown;
   char *new_buf = realloc (buf, new_buffer_size);
diff --git a/modules/backupfile b/modules/backupfile
index 42c8c9ed5..342a7bdff 100644
--- a/modules/backupfile
+++ b/modules/backupfile
@@ -21,11 +21,11 @@ intprops
 memcmp
 opendirat
 readdir
+realloc-gnu
 renameatu
 stdbool
 stdint
 xalloc-die
-xalloc-oversized
 
 configure.ac:
 gl_BACKUPFILE
-- 
2.27.0




[PATCH 1/8] safe-alloc: improve doc

2021-04-18 Thread Paul Eggert
* doc/safe-alloc.texi: Clarify that reallocating an array appends
uninitialized storage.  Say ‘sizeof *p’ rather than ‘sizeof(*p)’
which would need a space before the paren to follow GNU style.
---
 ChangeLog   |  5 +
 doc/safe-alloc.texi | 14 +-
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ab6045fd3..d2d12058e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2021-04-18  Paul Eggert  
 
+   safe-alloc: improve doc
+   * doc/safe-alloc.texi: Clarify that reallocating an array appends
+   uninitialized storage.  Say ‘sizeof *p’ rather than ‘sizeof(*p)’
+   which would need a space before the paren to follow GNU style.
+
malloc-gnu-tests, etc.: test ptrdiff_t overflow
* modules/calloc-gnu-tests (Depends-on):
* modules/malloc-gnu-tests (Depends-on):
diff --git a/doc/safe-alloc.texi b/doc/safe-alloc.texi
index 60304472f..d40ec65b6 100644
--- a/doc/safe-alloc.texi
+++ b/doc/safe-alloc.texi
@@ -36,12 +36,14 @@ passed in as arguments when appropriate.
 It uses return values only for a success/failure error condition flag,
 and annotates them with GCC's @code{__warn_unused_result__} attribute.
 @item
-It uses @code{calloc} instead of @code{malloc}.
+When allocating a fresh array, it uses @code{calloc} instead of
+@code{malloc} so that the array's contents are zeroed.
+However, memory added to an already-existing array is uninitialized.
 @end itemize
 
 @defmac {int} ALLOC (ptr)
 @findex ALLOC
-Allocate @code{sizeof(*ptr)} bytes of memory and store the address of
+Allocate @code{sizeof *ptr} bytes of memory and store the address of
 allocated memory in @code{ptr}.  Fill the newly allocated memory with
 zeros.
 
@@ -50,7 +52,7 @@ Returns @minus{}1 on failure, 0 on success.
 
 @defmac {int} ALLOC_N (ptr, count)
 @findex ALLOC_N
-Allocate an array of @code{count} elements, each @code{sizeof(*ptr)}
+Allocate an array of @code{count} elements, each @code{sizeof *ptr}
 bytes long, and store the address of allocated memory in
 @code{ptr}.  Fill the newly allocated memory with zeros.
 
@@ -59,7 +61,7 @@ Returns @minus{}1 on failure, 0 on success.
 
 @defmac {int} ALLOC_N_UNINITIALIZED (ptr, count)
 @findex ALLOC_N_UNINITIALIZED
-Allocate an array of @code{count} elements, each @code{sizeof(*ptr)}
+Allocate an array of @code{count} elements, each @code{sizeof *ptr}
 bytes long, and store the address of allocated memory in
 @code{ptr}.  The allocated memory is not initialized.
 
@@ -69,9 +71,11 @@ Returns @minus{}1 on failure, 0 on success.
 @defmac {int} REALLOC_N (ptr, count)
 @findex REALLOC_N
 Reallocate the memory pointed to by @code{ptr} to be big enough to hold
-at least @code{count} elements, each @code{sizeof(*ptr)} bytes long,
+at least @code{count} elements, each @code{sizeof *ptr} bytes long,
 and store the address of allocated memory in @code{ptr}.  If
 reallocation fails, the @code{ptr} variable is not modified.
+If the new array is smaller than the old one, discard excess contents;
+if larger, the newly added storage is not initialized.
 
 Returns @minus{}1 on failure, 0 on success.
 @end defmac
-- 
2.27.0




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Bruno Haible
Paul Eggert wrote:
> I installed the attached instead, as this is simpler.

Thanks!

> If there are 
> problems with PTRDIFF_MAX + 1, the test program might thrash or maybe 
> even crash the kernel, but that's good enough since there shouldn't be 
> problems.

Agree.

Bruno




Re: [PATCH] malloc, realloc: fix recently-introduced #undef typos

2021-04-18 Thread Paul Eggert

On 4/16/21 7:53 PM, Bruno Haible wrote:

+   malloc, realloc: fix recently-introduced #undef typos

That must have been more than a typo? It must have been an endless recursion?


Yes, they were typos that caused infloops. But little harm done; I don't 
think they escaped into any distributions.




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Paul Eggert

On 4/18/21 1:23 PM, Bruno Haible wrote:

If we put the test in a module that is marked as

 Status:
 privileged-test


It shouldn't require root access to test.

I installed the attached instead, as this is simpler. If there are 
problems with PTRDIFF_MAX + 1, the test program might thrash or maybe 
even crash the kernel, but that's good enough since there shouldn't be 
problems. These tests are not immune to arbitrary compiler optimization 
tricks but it's not worth the trouble to try to bypass the trucks.
>From 4d58319de4759923a6661a7c05b08cbbd335285b Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sun, 18 Apr 2021 15:29:54 -0700
Subject: [PATCH] malloc-gnu-tests, etc.: test ptrdiff_t overflow

* modules/calloc-gnu-tests (Depends-on):
* modules/malloc-gnu-tests (Depends-on):
* modules/realloc-gnu-tests (Depends-on): Add stdint.
* tests/test-calloc-gnu.c (main):
* tests/test-malloc-gnu.c (main):,
* tests/test-realloc-gnu.c (main): Test for ptrdiff_t overflow.
---
 ChangeLog |  8 
 modules/calloc-gnu-tests  |  1 +
 modules/malloc-gnu-tests  |  1 +
 modules/realloc-gnu-tests |  1 +
 tests/test-calloc-gnu.c   | 14 +-
 tests/test-malloc-gnu.c   | 11 ++-
 tests/test-realloc-gnu.c  | 10 ++
 7 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dd491f07b..ab6045fd3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2021-04-18  Paul Eggert  
 
+	malloc-gnu-tests, etc.: test ptrdiff_t overflow
+	* modules/calloc-gnu-tests (Depends-on):
+	* modules/malloc-gnu-tests (Depends-on):
+	* modules/realloc-gnu-tests (Depends-on): Add stdint.
+	* tests/test-calloc-gnu.c (main):
+	* tests/test-malloc-gnu.c (main):,
+	* tests/test-realloc-gnu.c (main): Test for ptrdiff_t overflow.
+
 	malloc-gnu, etc.: prefer AS_CASE to woolly AS_IF
 	* m4/calloc.m4 (_AC_FUNC_CALLOC_IF):
 	* m4/malloc.m4 (_AC_FUNC_MALLOC_IF):
diff --git a/modules/calloc-gnu-tests b/modules/calloc-gnu-tests
index 996db23b9..a4804fd28 100644
--- a/modules/calloc-gnu-tests
+++ b/modules/calloc-gnu-tests
@@ -2,6 +2,7 @@ Files:
 tests/test-calloc-gnu.c
 
 Depends-on:
+stdint
 
 configure.ac:
 
diff --git a/modules/malloc-gnu-tests b/modules/malloc-gnu-tests
index 75f7e4f52..9a6f01cfa 100644
--- a/modules/malloc-gnu-tests
+++ b/modules/malloc-gnu-tests
@@ -2,6 +2,7 @@ Files:
 tests/test-malloc-gnu.c
 
 Depends-on:
+stdint
 
 configure.ac:
 
diff --git a/modules/realloc-gnu-tests b/modules/realloc-gnu-tests
index 959d5d408..9d26260ba 100644
--- a/modules/realloc-gnu-tests
+++ b/modules/realloc-gnu-tests
@@ -2,6 +2,7 @@ Files:
 tests/test-realloc-gnu.c
 
 Depends-on:
+stdint
 
 configure.ac:
 
diff --git a/tests/test-calloc-gnu.c b/tests/test-calloc-gnu.c
index 953bd778b..eb336e1a6 100644
--- a/tests/test-calloc-gnu.c
+++ b/tests/test-calloc-gnu.c
@@ -17,6 +17,7 @@
 #include 
 
 #include 
+#include 
 
 /* Return 8.
Usual compilers are not able to infer something about the return value.  */
@@ -49,7 +50,7 @@ main ()
  'volatile' is needed to defeat an incorrect optimization by clang 10,
  see .  */
   {
-void * volatile p = calloc ((size_t) -1 / 8 + 1, eight ());
+void * volatile p = calloc (SIZE_MAX / 8 + 1, eight ());
 if (p != NULL)
   {
 free (p);
@@ -57,5 +58,16 @@ main ()
   }
   }
 
+  /* Likewise for PTRDIFF_MAX.  */
+  if (PTRDIFF_MAX / 8 < SIZE_MAX)
+{
+  void * volatile p = calloc (PTRDIFF_MAX / 8 + 1, eight ());
+  if (p != NULL)
+{
+  free (p);
+  return 2;
+}
+}
+
   return 0;
 }
diff --git a/tests/test-malloc-gnu.c b/tests/test-malloc-gnu.c
index 58a697f72..ce7e4fec2 100644
--- a/tests/test-malloc-gnu.c
+++ b/tests/test-malloc-gnu.c
@@ -17,6 +17,7 @@
 #include 
 
 #include 
+#include 
 
 int
 main ()
@@ -25,7 +26,15 @@ main ()
   char *p = malloc (0);
   if (p == NULL)
 return 1;
-
   free (p);
+
+  /* Check that malloc (n) fails when n exceeds PTRDIFF_MAX.  */
+  if (PTRDIFF_MAX < SIZE_MAX)
+{
+  size_t n = PTRDIFF_MAX, n1 = n + 1;
+  if (malloc (n1) != NULL)
+return 1;
+}
+
   return 0;
 }
diff --git a/tests/test-realloc-gnu.c b/tests/test-realloc-gnu.c
index 296852049..9c7344f15 100644
--- a/tests/test-realloc-gnu.c
+++ b/tests/test-realloc-gnu.c
@@ -17,6 +17,7 @@
 #include 
 
 #include 
+#include 
 
 int
 main ()
@@ -26,6 +27,15 @@ main ()
   if (p == NULL)
 return 1;
 
+  /* Check that realloc (p, n) fails when p is non-null and n exceeds
+ PTRDIFF_MAX.  */
+  if (PTRDIFF_MAX < SIZE_MAX)
+{
+  size_t n = PTRDIFF_MAX, n1 = n + 1;
+  if (realloc (p, n1) != NULL)
+return 1;
+}
+
   free (p);
   return 0;
 }
-- 
2.27.0



Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Bruno Haible
Paul Eggert wrote:
> > For example, if my package never calls malloc (0) but desires portability
> > to native Windows, would I want that *every* malloc call on *all*
> > non-glibc platforms goes through hoops before it reaches the malloc()
> > function in libc?
> 
> I would want that, yes, because that'd be more reliable than what we 
> were doing. Any performance penalty on non-GNU platforms is surely 
> insignificant in real applications, and so is outweighed by the 
> reliability improvement.

I don't disagree — as I can't measure reliability quantitatively.
Just wanted to give the reasoning that had led to the existing distinction
between 'malloc-posix' and 'malloc-gnu'.

Bruno




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Paul Eggert

On 4/18/21 5:11 AM, Bruno Haible wrote:

Paul Eggert wrote:

Come to think of it, why do we have both malloc-gnu and malloc-posix
modules (and similarly for calloc and realloc)?


Package owners had two decisions to make:
   "Does my package ever call malloc (0)? - If yes, I need 'malloc-gnu'."
   "Does my package attempt portability to native Windows? - If yes, I
need 'malloc-posix'."


Sure, but that sort of approach doesn't scale well. Now that we know the 
issues better, that approach would require package owners to answer 11 
questions:


A (for malloc, realloc, calloc). Does my package need errno to be set 
when malloc/realloc/calloc fails?


B (for malloc, realloc, calloc). Does my package require 
malloc/realloc/calloc to fail if it would create an object with more 
than PTRDIFF_MAX bytes?


C (for malloc, realloc, calloc). Does my package require malloc/calloc 
to return NULL if and only if it fails, and similarly for realloc (P, N) 
when !P || N?


D (for realloc). Does my package require realloc (P, 0) with nonnull P 
to free P and return NULL?


E (for calloc). Does my package require calloc (N, S) to fail when N * S 
would exceed SIZE_MAX?


And I've probably forgotten one or more questions.

Should we have 11 different modules, one for each question? Surely not. 
We shouldn't expect other packages to carefully select exactly which of 
these 11 questions they need GNU compatibility with. Such a selection 
will be error-prone and won't be well-tested if we get the selections wrong.


It's also not reasonable to test all 2**11 combinations of answers to 
these questions. Some combinations will never occur, and others will be 
rare and hard to be tested.


Instead, I suggest that we simply implement malloc, realloc and calloc 
the GNU way on all platforms. Packages that rely on any GNU malloc 
feature can simply require the malloc-gnu module without worrying about 
individual questions.


Come to think of it, it might be better to have a single module (say, 
alloc-gnu) check and fix all three functions (malloc, realloc, calloc) 
as that'd be simpler yet.



For example, if my package never calls malloc (0) but desires portability
to native Windows, would I want that *every* malloc call on *all*
non-glibc platforms goes through hoops before it reaches the malloc()
function in libc?


I would want that, yes, because that'd be more reliable than what we 
were doing. Any performance penalty on non-GNU platforms is surely 
insignificant in real applications, and so is outweighed by the 
reliability improvement. Admittedly it's hard to measure the reliability 
improvement, but I've already fixed an unlikely bug or two as part of 
this cleanup, and I won't be surprised to fix more.




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Bruno Haible
Hi Paul,

> > How about extending the unit test (tests/test-malloc-gnu.c) accordingly?
> 
> Won't that raise the possibility of the tests being too expensive, in 
> case the C library actually attempts to allocate PTRDIFF_MAX + 1 bytes?

In those cases where our code has a bug and the xalloc_oversized test in
malloc.c is not effective, yes, the test program may allocate a lot of memory.
If we put the test in a module that is marked as

Status:
privileged-test

normal users will never get to execute this test.

Bruno




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Paul Eggert

On 4/18/21 5:13 AM, Bruno Haible wrote:

How about extending the unit test (tests/test-malloc-gnu.c) accordingly?


Won't that raise the possibility of the tests being too expensive, in 
case the C library actually attempts to allocate PTRDIFF_MAX + 1 bytes? 
(I'm looking at you, 64-bit Hurd. :-)


I see we're already doing something similar with size_t in 
test-reallocarray.c but I suspect that test isn't often run because 
reallocarray isn't much used yet. Plus, that test won't use up much 
resources even on typical buggy hosts, because size_t overflow wraps around.




Re: gl_list API

2021-04-18 Thread Ben Pfaff
On Tue, Apr 6, 2021 at 1:30 PM Bruno Haible  wrote:
> Paul Eggert wrote:
> > Yes, that would be portable. But that cast indicates another problem
> > with the API. It should return void *, not void const * (think of strchr
> > as the model here).
>
> strchr is a bad model here: You pass it a pointer to a read-only storage
> (such as a literal string) and receive a pointer that you "can" write
> to: The compiler cannot warn about
>strchr ("literal", 'e') [2] = 'x';

I've gotten in the habit of having two functions in cases like this. If
strchr were designed according to the principles that I try to apply,
we'd have functions like this:

const char *strchr (const char *, int);
char *strchr_rw (char *, int);

The implementation of strchr is then just a wrapper around the
strchr_rw():

const char *
strchr (const char *s, int c)
{
return strchr_rw ((char *) s, c);
}

although if I'm doing this in PSPP I would probably use CONST_CAST:
return strchr_rw (CONST_CAST (char *, s), c);



Re: cast macros

2021-04-18 Thread Ben Pfaff
On Tue, Apr 6, 2021 at 4:04 PM Bruno Haible  wrote:
>
> I wrote:
> > So far we have been lacking type-casts that warn for invalid use;
> > it is well possible that with the PSPP macros (or with Marc's approach
> > of _Generic), we can design a type-safe wrapper around gl_list.h
>
> Here is a simplified test case: The simplest container type is a box type,
> that contain just one value. Can one of you complete this code, so that
> it produces the warnings / no warnings as indicated?
>
> 
> typedef const void ** gl_box_t;
>
> extern gl_box_t create_box (const void *);
> extern const void *box_get_value (gl_box_t);
>
> #include "cast.h"
>
> /* CAST_TO_FROM (TO, FROM, EXPR)
>gives a warning if EXPR is not of type FROM,
>and returns EXPR, cast to type TO.  */
>
> struct foo;
> #define ELEMENT_TYPE struct foo *
> #define CREATE_BOX(V) \
>   create_box (CAST_TO_FROM (const void *, ELEMENT_TYPE, V))
> #define BOX_GET_VALUE(BOX) \
>   CAST_TO_FROM (ELEMENT_TYPE, const void *, box_get_value (BOX))
>
> struct foo *a;
> struct foo *b;
> const void *c;
> void *d;
> int *i;
>
> int
> main ()
> {
>   (void) CAST_TO_FROM (int *, const void *, c); // no warning
>   (void) CAST_TO_FROM (int *, void *, d);   // no warning
>   (void) CAST_TO_FROM (int *, const void *, d); // no warning
>   (void) CAST_TO_FROM (int *, void *, c);   // warning
>   (void) CAST_TO_FROM (int *, void *, i);   // warning
>   (void) CAST_TO_FROM (int *, char *, i);   // warning
>
>   gl_box_t box = CREATE_BOX (a);// no warning
>   return BOX_GET_VALUE (box) == b;  // no warning
> }
> 

I spent some time experimenting and I don't know a way to do that.

One way to come close, using GCC extensions:
  #define CAST_TO_FROM(to, from, expr) ({ \
_Static_assert (__builtin_types_compatible_p (typeof(expr), from)); \
(to) (expr);  \
  })
but this will give an unwanted warning for
  (void) CAST_TO_FROM (int *, const void *, d); // no warning
because the 'const' is not outermost.

Another way, without GCC extensions, is:
  #define CAST_TO_FROM(to, from, expr) ({ \
(void) sizeof ((from) (expr) == (expr));  \
(to) (expr);  \
  })
but this fails to warn for either of the following because void mixes with
other types so freely in C:
  (void) CAST_TO_FROM (int *, void *, c);   // warning
  (void) CAST_TO_FROM (int *, void *, i);   // warning



Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Paul Eggert

On 4/18/21 5:13 AM, Bruno Haible wrote:


* m4/realloc.m4 (_AC_FUNC_REALLOC_IF):
Don’t start with a newline.


This is not very robust. We usually don't care about newlines or useless
indentation in the generated configure.ac any more.


Yes, I made that change only because I ran into some shell syntax error 
and the change fixed it. I don't recall what the error was and can't 
reproduce it now, so the attached first patch reverts that change.


If we run into further problems in this area, though, perhaps the patch 
should go back in.  Autoconf (which _AC_FUNC_REALLOC_IF is taken from) 
does care about leading newlines, and even if we have a different API in 
Gnulib surely it's better to stick to the Autoconf API in 
Autoconf-replacing macros.



  if test $REPLACE_REALLOC = 0; then
_AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC=1])
  fi


I confess I don't like the style as much: it makes the shell code a bit 
less readable, at least to me. But it appears that this style isn't 
needed anyway.


I noticed some other incompatibilities with Autoconf _AC_FUNC_REALLOC_IF 
etc. and fixed them too in the attached first patch.


The second patch switches from AS_IF to AS_CASE as that's cleaner in the 
Gnulib version.
From c08e261c39ef3840b1cb1ae7c04c669c469cd91d Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sun, 18 Apr 2021 11:23:24 -0700
Subject: [PATCH 1/2] malloc-gnu, etc.: sync better with Autoconf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* m4/calloc.m4 (_AC_FUNC_CALLOC_IF):
* m4/malloc.m4 (_AC_FUNC_MALLOC_IF):
* m4/realloc.m4 (_AC_FUNC_REALLOC_IF):
Avoid some unnecessary differences from Autoconf’s versions.
Separate our platforms into a different line so that it’s easier
to diff.  Use AS_IF in case the args use AC_REQUIRE.
However, don’t bother with omitting the first newline, as
omitting the newline is not Gnulib style and the difference
doesn’t seem to matter here.
---
 ChangeLog | 13 +
 m4/calloc.m4  | 15 +--
 m4/malloc.m4  | 24 ++--
 m4/realloc.m4 | 24 ++--
 4 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 38311496b..fa630a758 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2021-04-18  Paul Eggert  
+
+	malloc-gnu, etc.: sync better with Autoconf
+	* m4/calloc.m4 (_AC_FUNC_CALLOC_IF):
+	* m4/malloc.m4 (_AC_FUNC_MALLOC_IF):
+	* m4/realloc.m4 (_AC_FUNC_REALLOC_IF):
+	Avoid some unnecessary differences from Autoconf’s versions.
+	Separate our platforms into a different line so that it’s easier
+	to diff.  Use AS_IF in case the args use AC_REQUIRE.
+	However, don’t bother with omitting the first newline, as
+	omitting the newline is not Gnulib style and the difference
+	doesn’t seem to matter here.
+
 2021-04-18  Bruno Haible  
 
 	malloc-posix, realloc-posix, calloc-posix: Document affected platforms.
diff --git a/m4/calloc.m4 b/m4/calloc.m4
index 143f3bc3f..776979d25 100644
--- a/m4/calloc.m4
+++ b/m4/calloc.m4
@@ -1,4 +1,4 @@
-# calloc.m4 serial 24
+# calloc.m4 serial 25
 
 # Copyright (C) 2004-2021 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -16,7 +16,8 @@
 # -
 # If calloc is compatible with GNU calloc, run IF-WORKS, otherwise, IF-NOT.
 AC_DEFUN([_AC_FUNC_CALLOC_IF],
-[ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+[
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CACHE_CHECK([whether calloc (0, n) and calloc (n, 0) return nonnull],
 [ac_cv_func_calloc_0_nonnull],
 [if test $cross_compiling != yes; then
@@ -46,14 +47,8 @@ AC_DEFUN([_AC_FUNC_CALLOC_IF],
esac
  fi
 ])
-  case "$ac_cv_func_calloc_0_nonnull" in
-*yes)
-  $1
-  ;;
-*)
-  $2
-  ;;
-  esac
+  AS_IF([case $ac_cv_func_calloc_0_nonnull in *yes) :;; *) false;; esac],
+[$1], [$2])
 ])
 
 
diff --git a/m4/malloc.m4 b/m4/malloc.m4
index 503da2cf8..9734dab05 100644
--- a/m4/malloc.m4
+++ b/m4/malloc.m4
@@ -1,20 +1,21 @@
-# malloc.m4 serial 23
+# malloc.m4 serial 24
 dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 # This is adapted with modifications from upstream Autoconf here:
-# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=04be2b7a29d65d9a08e64e8e56e594c91749598c
+# https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n949
 AC_DEFUN([_AC_FUNC_MALLOC_IF],
-[ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
   AC_CACHE_CHECK([whether malloc (0) returns nonnull],
 [ac_cv_func_malloc_0_nonnull],
 [AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
   [[#include 
   ]],
-  

Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Bruno Haible
Hi Paul,

> * m4/realloc.m4 (_AC_FUNC_REALLOC_IF):
> Don’t start with a newline.

This is not very robust. We usually don't care about newlines or useless
indentation in the generated configure.ac any more. Therefore future
edits may reintroduce a newline here. It would be more robust to change

  test $REPLACE_REALLOC = 1 || _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC=1])

to

  if test $REPLACE_REALLOC = 0; then
_AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC=1])
  fi

Bruno




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Bruno Haible
> In glibc 2.30 and later, malloc, realloc and calloc reject
> attempts to create objects larger than PTRDIFF_MAX bytes.
> This patch changes malloc-gnu etc. to support this behavior
> on non-GNU hosts.

How about extending the unit test (tests/test-malloc-gnu.c) accordingly?

Bruno




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Bruno Haible
Paul Eggert wrote:
> Come to think of it, why do we have both malloc-gnu and malloc-posix 
> modules (and similarly for calloc and realloc)?

Package owners had two decisions to make:
  "Does my package ever call malloc (0)? - If yes, I need 'malloc-gnu'."
  "Does my package attempt portability to native Windows? - If yes, I
   need 'malloc-posix'."

> In other words, I suggest that we remove malloc-posix, realloc-posix and 
> calloc-posix

Think about the effects on the package on non-glibc platforms, from the
perspective of the package owner.
For example, if my package never calls malloc (0) but desires portability
to native Windows, would I want that *every* malloc call on *all*
non-glibc platforms goes through hoops before it reaches the malloc()
function in libc?

Bruno




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Bruno Haible
> * doc/posix-functions/calloc.texi:
> * doc/posix-functions/malloc.texi:
> * doc/posix-functions/realloc.texi:
> Mention ptrdiff_t issues, and go into more detail about what
> the gnu extension module does.

The patch dropped the list of affected platforms. However this list is
important so that
  - users can decide whether they want to pull in the module,
  - I know on which platforms to conduct tests when preparing changes in this
area.


2021-04-18  Bruno Haible  

malloc-posix, realloc-posix, calloc-posix: Document affected platforms.
* doc/posix-functions/malloc.texi: Re-add platforms list.
* doc/posix-functions/realloc.texi: Likewise.
* doc/posix-functions/calloc.texi: Likewise.

diff --git a/doc/posix-functions/calloc.texi b/doc/posix-functions/calloc.texi
index 9ba40c0..57bec4d 100644
--- a/doc/posix-functions/calloc.texi
+++ b/doc/posix-functions/calloc.texi
@@ -28,6 +28,7 @@ It fixes this portability problem:
 
 @itemize
 @item
-On some platforms, @code{calloc (0, s)} and @code{calloc (n, 0)}
-return @code{NULL} on success.
+@code{calloc (0, s)} and @code{calloc (n, 0)} return @code{NULL} on success
+on some platforms:
+AIX 7.2.
 @end itemize
diff --git a/doc/posix-functions/malloc.texi b/doc/posix-functions/malloc.texi
index 8295173..028f1dc 100644
--- a/doc/posix-functions/malloc.texi
+++ b/doc/posix-functions/malloc.texi
@@ -26,5 +26,6 @@ by fixing this portability problem:
 
 @itemize
 @item
-On some platforms, @code{malloc (0)} returns @code{NULL} on success.
+@code{malloc (0)} returns @code{NULL} on success on some platforms:
+AIX 7.2.
 @end itemize
diff --git a/doc/posix-functions/realloc.texi b/doc/posix-functions/realloc.texi
index 282e360..009bdab 100644
--- a/doc/posix-functions/realloc.texi
+++ b/doc/posix-functions/realloc.texi
@@ -39,7 +39,8 @@ It fixes these portability problems:
 
 @itemize
 @item
-On some platforms, @code{realloc (NULL, 0)} returns @code{NULL} on success.
+@code{realloc (NULL, 0)} returns @code{NULL} on success on some platforms:
+AIX 7.2.
 
 @item
 On some platforms, @code{realloc (p, 0)} with non-null @code{p}




More systematic file naming

2021-04-18 Thread Bruno Haible
This gets closer to a systematic naming of the *.m4 files of header
replacements. Only stdint.m4 and inttypes.m4 are not aligned.


2021-04-18  Bruno Haible  

More systematic file naming.
* m4/ctype_h.m4: Renamed from m4/ctype.m4.
* m4/threads_h.m4: Renamed from m4/threads.m4.
* m4/uchar_h.m4: Renamed from m4/uchar.m4.

diff --git a/m4/threads_h.m4 b/m4/threads_h.m4
index 53ec6d5..adda3e6 100644
--- a/m4/threads_h.m4
+++ b/m4/threads_h.m4
@@ -1,4 +1,4 @@
-# threads.m4 serial 10
+# threads_h.m4 serial 10
 dnl Copyright (C) 2019-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/uchar_h.m4 b/m4/uchar_h.m4
index 1923f17..55cc33a 100644
--- a/m4/uchar_h.m4
+++ b/m4/uchar_h.m4
@@ -1,4 +1,4 @@
-# uchar.m4 serial 20
+# uchar_h.m4 serial 20
 dnl Copyright (C) 2019-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/modules/ctype b/modules/ctype
index 0196dfa..60d7d5f 100644
--- a/modules/ctype
+++ b/modules/ctype
@@ -3,7 +3,7 @@ A  that conforms to C99.
 
 Files:
 lib/ctype.in.h
-m4/ctype.m4
+m4/ctype_h.m4
 
 Depends-on:
 extern-inline
diff --git a/modules/threads-h b/modules/threads-h
index 37cc6d8..0ea7a48 100644
--- a/modules/threads-h
+++ b/modules/threads-h
@@ -12,7 +12,7 @@ lib/windows-once.h
 lib/windows-cond.h
 lib/windows-tls.h
 lib/windows-initguard.h
-m4/threads.m4
+m4/threads_h.m4
 m4/threadlib.m4
 build-aux/config.rpath
 
diff --git a/modules/uchar b/modules/uchar
index a65fce2..e57ee99 100644
--- a/modules/uchar
+++ b/modules/uchar
@@ -3,7 +3,7 @@ A GNU-like .
 
 Files:
 lib/uchar.in.h
-m4/uchar.m4
+m4/uchar_h.m4
 m4/stdint.m4
 
 Depends-on:




Re: Interference between two installations of gnulib

2021-04-18 Thread Bruno Haible
I wrote:
> The problem is that the macro gl_STDIO_H_REQUIRE_DEFAULTS must only be 
> invoked,
> never AC_REQUIREd. Hence all gl_STDIO_MODULE_INDICATOR invocations must also
> only be invoked, never AC_REQUIREd.

This deserves to be documented.


2021-04-18  Bruno Haible  

Add comments after 2021-04-11 change.
* m4/*_h.m4: Add comments regarding *_REQUIRE_DEFAULTS and
*_MODULE_INDICATOR macros.

diff --git a/m4/arpa_inet_h.m4 b/m4/arpa_inet_h.m4
index 868ebdf..a3ba256 100644
--- a/m4/arpa_inet_h.m4
+++ b/m4/arpa_inet_h.m4
@@ -1,4 +1,4 @@
-# arpa_inet_h.m4 serial 16
+# arpa_inet_h.m4 serial 17
 dnl Copyright (C) 2006, 2008-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,6 +40,10 @@ AC_DEFUN_ONCE([gl_ARPA_INET_H],
 ]], [inet_ntop inet_pton])
 ])
 
+# gl_ARPA_INET_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
 AC_DEFUN([gl_ARPA_INET_MODULE_INDICATOR],
 [
   dnl Ensure to expand the default settings once only.
@@ -47,6 +51,9 @@ AC_DEFUN([gl_ARPA_INET_MODULE_INDICATOR],
   gl_MODULE_INDICATOR_SET_VARIABLE([$1])
 ])
 
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd.  It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
 AC_DEFUN([gl_ARPA_INET_H_REQUIRE_DEFAULTS],
 [
   m4_defun(GL_MODULE_INDICATOR_PREFIX[_ARPA_INET_H_MODULE_INDICATOR_DEFAULTS], 
[
diff --git a/m4/ctype.m4 b/m4/ctype.m4
index d48847a..efdae45 100644
--- a/m4/ctype.m4
+++ b/m4/ctype.m4
@@ -1,4 +1,4 @@
-# ctype_h.m4 serial 8
+# ctype_h.m4 serial 9
 dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -17,6 +17,10 @@ AC_DEFUN_ONCE([gl_CTYPE_H],
 ]], [isblank])
 ])
 
+# gl_CTYPE_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
 AC_DEFUN([gl_CTYPE_MODULE_INDICATOR],
 [
   dnl Ensure to expand the default settings once only.
@@ -24,6 +28,9 @@ AC_DEFUN([gl_CTYPE_MODULE_INDICATOR],
   gl_MODULE_INDICATOR_SET_VARIABLE([$1])
 ])
 
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd.  It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
 AC_DEFUN([gl_CTYPE_H_REQUIRE_DEFAULTS],
 [
   m4_defun(GL_MODULE_INDICATOR_PREFIX[_CTYPE_H_MODULE_INDICATOR_DEFAULTS], [
diff --git a/m4/dirent_h.m4 b/m4/dirent_h.m4
index 3bcf34b..17e2a20 100644
--- a/m4/dirent_h.m4
+++ b/m4/dirent_h.m4
@@ -1,4 +1,4 @@
-# dirent_h.m4 serial 18
+# dirent_h.m4 serial 19
 dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -27,6 +27,10 @@ AC_DEFUN_ONCE([gl_DIRENT_H],
 ]], [alphasort closedir dirfd fdopendir opendir readdir rewinddir scandir])
 ])
 
+# gl_DIRENT_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
 AC_DEFUN([gl_DIRENT_MODULE_INDICATOR],
 [
   dnl Ensure to expand the default settings once only.
@@ -36,6 +40,9 @@ AC_DEFUN([gl_DIRENT_MODULE_INDICATOR],
   gl_MODULE_INDICATOR_FOR_TESTS([$1])
 ])
 
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd.  It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
 AC_DEFUN([gl_DIRENT_H_REQUIRE_DEFAULTS],
 [
   m4_defun(GL_MODULE_INDICATOR_PREFIX[_DIRENT_H_MODULE_INDICATOR_DEFAULTS], [
diff --git a/m4/fcntl_h.m4 b/m4/fcntl_h.m4
index 822bf02..aba4473 100644
--- a/m4/fcntl_h.m4
+++ b/m4/fcntl_h.m4
@@ -1,4 +1,4 @@
-# serial 19
+# serial 20
 # Configure fcntl.h.
 dnl Copyright (C) 2006-2007, 2009-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
@@ -26,6 +26,10 @@ AC_DEFUN_ONCE([gl_FCNTL_H],
 ]], [fcntl openat])
 ])
 
+# gl_FCNTL_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
 AC_DEFUN([gl_FCNTL_MODULE_INDICATOR],
 [
   dnl Ensure to expand the default settings once only.
@@ -35,6 +39,9 @@ AC_DEFUN([gl_FCNTL_MODULE_INDICATOR],
   

doc: Update for FreeBSD 13.0/arm64

2021-04-18 Thread Bruno Haible
2021-04-18  Bruno Haible  

doc: Update for FreeBSD 13.0/arm64.
* doc/posix-headers/stdint.texi: Mention FreeBSD 13 bug.
* m4/stdint.m4: Update comment.

diff --git a/doc/posix-headers/stdint.texi b/doc/posix-headers/stdint.texi
index 6775bea..784799b 100644
--- a/doc/posix-headers/stdint.texi
+++ b/doc/posix-headers/stdint.texi
@@ -15,7 +15,7 @@ This header file is very incomplete on some platforms.
 @item
 The values of @code{SIG_ATOMIC_MIN} and @code{SIG_ATOMIC_MAX} are incorrect
 on some platforms:
-FreeBSD 6.2 / ia64.
+FreeBSD 6.2/ia64, FreeBSD 13.0/arm64.
 @item
 The value of @code{WINT_MAX} is incorrect on some platforms:
 mingw.
diff --git a/m4/stdint.m4 b/m4/stdint.m4
index 3406445..2eb1652 100644
--- a/m4/stdint.m4
+++ b/m4/stdint.m4
@@ -1,4 +1,4 @@
-# stdint.m4 serial 59
+# stdint.m4 serial 60
 dnl Copyright (C) 2001-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -170,7 +170,7 @@ struct s {
   PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t)
   && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t)
   ? 1 : -1;
-  /* Detect bug in FreeBSD 6.0 / ia64.  */
+  /* Detect bug in FreeBSD 6.0/ia64 and FreeBSD 13.0/arm64.  */
   int check_SIG_ATOMIC:
   SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t)
   && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t)