]> Savannah Git Hosting - gnulib.git/commitdiff
realloc: Optionally check for undefined behaviour.
authorBruno Haible <bruno@clisp.org>
Mon, 21 Oct 2024 13:29:40 +0000 (15:29 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 21 Oct 2024 15:14:01 +0000 (17:14 +0200)
* 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.

ChangeLog
lib/realloc.c
m4/realloc.m4

index 0b7094e6505d0f412281ab5042a1e7f511c36ef1..4e5e61b6548ea87dbc0e4bfd2fa883a9c2b61d3d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+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)
index 0573139625e750c314b23a3b91cec63f658d6113..5cfe3bc7472da68a0ab5732102ad271116e590ef 100644 (file)
@@ -42,8 +42,19 @@ rpl_realloc (void *p, size_t 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 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))
index e25f329c503338b9cd87cf56b00dae495989a065..f4d78f9622e4250510f7a3751e56447ed9430b81 100644 (file)
@@ -1,11 +1,23 @@
 # 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],
@@ -51,7 +63,9 @@ AC_DEFUN([gl_FUNC_REALLOC_GNU],
   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
@@ -65,7 +79,14 @@ AC_DEFUN([gl_FUNC_REALLOC_POSIX],
 [
   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
 ])