For glibc, implementing realloc (p, s) as realloc (p, s?s:1) suffices,
and it’s probably better to do it inline to aid static checking.
* lib/realloc.c (rpl_realloc) [_GL_INLINE_RPL_REALLOC]:
Remove, replacing with inline function in stdlib.h.
* lib/stdlib.in.h (_GL_INLINE_RPL_REALLOC): New macro.
(rpl_realloc): Define as inline if _GL_INLINE_RPL_REALLOC.
* m4/realloc.m4 (gl_FUNC_REALLOC_0_NONNULL):
Set REPLACE_REALLOC_FOR_REALLOC_POSIX=2 instead of 1,
if it’s close enough to glibc that the inline optimization is valid.
---
 ChangeLog       | 11 +++++++++++
 lib/realloc.c   | 24 ++++++++++++++----------
 lib/stdlib.in.h | 10 ++++++++++
 m4/realloc.m4   |  8 ++++++--
 4 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d646381a86..1617f3b58b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2024-11-04  Paul Eggert  <egg...@cs.ucla.edu>
 
+       realloc-posix: tune for glibc-like
+       For glibc, implementing realloc (p, s) as realloc (p, s?s:1) suffices,
+       and it’s probably better to do it inline to aid static checking.
+       * lib/realloc.c (rpl_realloc) [_GL_INLINE_RPL_REALLOC]:
+       Remove, replacing with inline function in stdlib.h.
+       * lib/stdlib.in.h (_GL_INLINE_RPL_REALLOC): New macro.
+       (rpl_realloc): Define as inline if _GL_INLINE_RPL_REALLOC.
+       * m4/realloc.m4 (gl_FUNC_REALLOC_0_NONNULL):
+       Set REPLACE_REALLOC_FOR_REALLOC_POSIX=2 instead of 1,
+       if it’s close enough to glibc that the inline optimization is valid.
+
        realloc-posix: use _GL_USE_STDLIB_ALLOC
        * lib/realloc.c (_GL_USE_STDLIB_ALLOC):
        New macro, which we can use now that we don’t use malloc.
diff --git a/lib/realloc.c b/lib/realloc.c
index e1c971eb06..e1198cf633 100644
--- a/lib/realloc.c
+++ b/lib/realloc.c
@@ -30,6 +30,8 @@
 # include <cheri.h>
 #endif
 
+#ifndef _GL_INLINE_RPL_REALLOC
+
 /* Change the size of an allocated block of memory P to N bytes,
    with error checking.  If P is NULL, use malloc.  Otherwise if N is zero,
    free P and return NULL.  */
@@ -41,7 +43,7 @@ rpl_realloc (void *p, size_t n)
 
   if (n == 0)
     {
-#if NEED_SANITIZED_REALLOC
+# if NEED_SANITIZED_REALLOC
       /* When P is non-null, ISO C23 §7.24.3.7.(3) says realloc (P, 0) has
          undefined behavior even though C17 and earlier partially defined
          the behavior.  Let the programmer know.
@@ -52,7 +54,7 @@ rpl_realloc (void *p, size_t n)
          we can revisit this code.  */
       if (p != NULL)
         abort ();
-#endif
+# endif
 
       /* realloc (NULL, 0) acts like glibc malloc (0), i.e., like malloc (1)
          except the caller cannot dereference any non-null return.
@@ -74,31 +76,33 @@ rpl_realloc (void *p, size_t n)
          matches BSD and V7 realloc, and requires no extra code at
          caller sites.  */
 
-#if !HAVE_REALLOC_0_NONNULL
+# if !HAVE_REALLOC_0_NONNULL
       n1 = 1;
-#endif
+# endif
     }
 
-#if !HAVE_MALLOC_PTRDIFF
+# if !HAVE_MALLOC_PTRDIFF
   ptrdiff_t signed_n;
   if (ckd_add (&signed_n, n, 0))
     {
       errno = ENOMEM;
       return NULL;
     }
-#endif
+# endif
 
   void *result = realloc (p, n1);
 
-#if !HAVE_MALLOC_POSIX
+# if !HAVE_MALLOC_POSIX
   if (result == NULL)
     errno = ENOMEM;
-#endif
+# endif
 
-#ifdef __CHERI_PURE_CAPABILITY__
+# ifdef __CHERI_PURE_CAPABILITY__
   if (result != NULL)
     result = cheri_bounds_set (result, n);
-#endif
+# endif
 
   return result;
 }
+
+#endif
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 0d5c076d06..7344157263 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -1461,14 +1461,24 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable 
- "
 
 #if @GNULIB_REALLOC_POSIX@
 # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@
+#  if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2
+#   define _GL_INLINE_RPL_REALLOC 1
+_GL_STDLIB_INLINE void *
+rpl_realloc (void *ptr, size_t size)
+{
+  return realloc (ptr, size ? size : 1);
+}
+#  endif
 #  if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
         || _GL_USE_STDLIB_ALLOC)
 #   undef realloc
 #   define realloc rpl_realloc
 #  endif
+#  if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ != 2
 _GL_FUNCDECL_RPL (realloc, void *,
                   (void *ptr, size_t size),
                   _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_NODISCARD);
+#  endif
 _GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size));
 # else
 #  if __GNUC__ >= 11 && !defined __clang__
diff --git a/m4/realloc.m4 b/m4/realloc.m4
index 4a3f2ea8ae..f34cc4c389 100644
--- a/m4/realloc.m4
+++ b/m4/realloc.m4
@@ -1,5 +1,5 @@
 # realloc.m4
-# serial 38
+# serial 39
 dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -73,5 +73,9 @@ AC_DEFUN([gl_FUNC_REALLOC_0_NONNULL],
     [*yes],
       [AC_DEFINE([HAVE_REALLOC_0_NONNULL], [1],
          [Define to 1 if realloc (..., 0) returns nonnull.])],
-    [REPLACE_REALLOC_FOR_REALLOC_POSIX=1])
+    
[AS_CASE([$gl_cv_func_realloc_sanitize,$gl_cv_malloc_ptrdiff,$gl_cv_func_malloc_posix,$host],
+       [yes,*,*,* | *,no,*,* | *,*,*no,* | *,*,*,aarch64c-*-freebsd*],
+         [REPLACE_REALLOC_FOR_REALLOC_POSIX=1],
+       [# Optimize for common case of glibc 2.1.1+ and compatibles.
+        REPLACE_REALLOC_FOR_REALLOC_POSIX=2])])
 ])
-- 
2.43.0


Reply via email to