+2024-10-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ realloc-posix: realloc (p, 0) yields nonnull
+ * lib/realloc.c: Include <stdckdint.h>, not "xalloc-oversized.h".
+ Use of xalloc_oversized replaced by ckd_add.
+ (rpl_realloc) [!NEED_SANITIZED_REALLOC]:
+ Treat realloc (p, 0) as if it were a realloc (p, 1) that never fails.
+ That’s easier, reduces module dependencies,
+ and better supports the future alloc-0-nonnull module.
+ * modules/realloc-posix (Depends-on): Remove free-posix,
+ malloc-posix, xalloc-oversized. Add stdckdint.
+
2024-10-29 Collin Funk <collin.funk1@gmail.com>
backupfile: Remove non-existent module dependency.
#include <stdlib.h>
#include <errno.h>
-
-#include "xalloc-oversized.h"
+#include <stdckdint.h>
/* Call the system's realloc below. This file does not define
_GL_USE_STDLIB_ALLOC because it needs Gnulib's malloc if present. */
void *
rpl_realloc (void *p, size_t n)
{
- if (p == NULL)
- return malloc (n);
-
if (n == 0)
{
#if NEED_SANITIZED_REALLOC
- /* ISO C 23 § 7.24.3.7.(3) says that this case is undefined behaviour.
- Let the programmer know that it occurred.
+ /* 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.
When the undefined-behaviour sanitizers report this case, i.e. when
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117233> and
<https://github.com/llvm/llvm-project/issues/113065>
have been closed and new releases of GCC and clang have been made,
- we can remove this code here. */
- abort ();
-#else
- free (p);
- return NULL;
+ we can revisit this code. */
+ if (p != NULL)
+ abort ();
#endif
+
+ /* When P is null, act like glibc malloc, i.e., like malloc (1)
+ except the caller cannot dereference any non-null return.
+
+ When P is non-null, POSIX.1-2024 extends C17 to say that
+ realloc (P, 0) either fails and returns a null pointer,
+ or succeeds by freeing P and then either:
+ (a) setting errno=EINVAL and returning a null pointer; or
+ (b) acting like a successful malloc (0).
+ GNU realloc acts like (a) except it does not set errno;
+ this conforms to C17 and to C23 but not to POSIX.1-2024.
+ Quite possibly future versions of POSIX will change,
+ due either to C23 or to (a)'s semantics being messy.
+ Act like (b), as that's easy, matches GNU, BSD and V7 malloc,
+ matches BSD and V7 realloc, and is convenient for Gnulib.
+ Do not fail if P is nonnull, though, as it's natural for callers
+ to assume that realloc (P, 0) can fail only when P is null. */
+
+ void *result = realloc (p, 1);
+ return result ? result : p;
}
- if (xalloc_oversized (n, 1))
+ ptrdiff_t signed_n;
+ if (ckd_add (&signed_n, n, 0))
{
errno = ENOMEM;
return NULL;