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