+2024-10-21 Bruno Haible <bruno@clisp.org>
+
+ realloc: Optionally check for undefined behaviour.
+ * m4/realloc.m4 (gl_FUNC_REALLOC_SANITIZED): New macro.
+ (gl_FUNC_REALLOC_POSIX): Require it. If a sanitized realloc is
+ requested, define NEED_SANITIZED_REALLOC and compile realloc.c.
+ (gl_FUNC_REALLOC_GNU): Require it. If a sanitized realloc is requested,
+ don't compile realloc.c a second time.
+ * lib/realloc.c (rpl_realloc): If NEED_SANITIZED_REALLOC is defined,
+ abort in the case of undefined behaviour.
+
2024-10-19 Paul Eggert <eggert@cs.ucla.edu>
realloc: more improvements for realloc (p, 0)
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 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;
+#endif
}
if (xalloc_oversized (n, 1))
# realloc.m4
-# serial 32
+# serial 33
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,
dnl with or without modifications, as long as this notice is preserved.
dnl This file is offered as-is, without any warranty.
+# An an experimental option, the user can request a sanitized realloc()
+# implementation, i.e. one that aborts upon undefined behaviour,
+# by setting
+# gl_cv_func_realloc_sanitize=yes
+# at configure time.
+AC_DEFUN([gl_FUNC_REALLOC_SANITIZED],
+[
+ AC_CACHE_CHECK([whether realloc should abort upon undefined behaviour],
+ [gl_cv_func_realloc_sanitize],
+ [test -n "$gl_cv_func_realloc_sanitize" || gl_cv_func_realloc_sanitize=no])
+])
+
# This is adapted with modifications from upstream Autoconf here:
# https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n1455
AC_DEFUN([_AC_FUNC_REALLOC_IF],
dnl gets defined already before this macro gets invoked. This helps
dnl if !(__VEC__ || __AIXVEC), and doesn't hurt otherwise.
- if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then
+ AC_REQUIRE([gl_FUNC_REALLOC_SANITIZED])
+ if test "$gl_cv_func_realloc_sanitize" = no \
+ && test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then
_AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC_FOR_REALLOC_GNU=1])
fi
])# gl_FUNC_REALLOC_GNU
[
AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
AC_REQUIRE([gl_FUNC_MALLOC_POSIX])
- if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then
+ AC_REQUIRE([gl_FUNC_REALLOC_SANITIZED])
+ if test "$gl_cv_func_realloc_sanitize" != no; then
REPLACE_REALLOC_FOR_REALLOC_POSIX=1
+ AC_DEFINE([NEED_SANITIZED_REALLOC], [1],
+ [Define to 1 if realloc should abort upon undefined behaviour.])
+ else
+ if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then
+ REPLACE_REALLOC_FOR_REALLOC_POSIX=1
+ fi
fi
])