On 5/11/20 2:11 PM, Bruno Haible wrote:

> xmalloc.c:113:10: warning: use of possibly-NULL '<unknown>' where non-null 
> expected [CWE-690] [-Wanalyzer-possible-null-argument]
> Since xmalloc (0) may be NULL, xmemdup may end up calling memcpy (NULL, p, 0).
> We know this is harmless, if no sanitizer is present at run time.
> But just to avoid triggering an undefined-behaviour sanitizer, we could treat 
> n == 0 specially.

To partially fix this I tuned xmalloc for when a GNU-compatible malloc is being
used by installing the attached patch. This is a micro-optimization for GNU
platforms (it omits a runtime test) and it pacifies GCC and/or other sanitizers
when a GNU-compatible malloc is being used. I hope that's good enough, since
people not using GNU-compatible malloc can either ignore the false alarm or add
the malloc-gnu module.
>From ffbb0ced8b2a01c2e355fa7d41db1232453f28b5 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 12 May 2020 09:24:05 -0700
Subject: [PATCH] xalloc: pacify -Wanalyzer-possible-null-argument

Problem reported for GCC 10.1.0 by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2020-05/msg00118.html
* lib/xmalloc.c (HAVE_GNU_MALLOC, HAVE_GNU_REALLOC): New constants.
(xmalloc): Suppress unnecessary check if HAVE_GNU_MALLOC.
(xrealloc): Suppress unnecssary check if HAVE_GNU_REALLOC.
---
 ChangeLog     |  9 +++++++++
 lib/xmalloc.c | 31 +++++++++++++++++++++----------
 2 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 58a7a67dc..ee83e22ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2020-05-12  Paul Eggert  <egg...@cs.ucla.edu>
+
+	xalloc: pacify -Wanalyzer-possible-null-argument
+	Problem reported for GCC 10.1.0 by Bruno Haible in:
+	https://lists.gnu.org/r/bug-gnulib/2020-05/msg00118.html
+	* lib/xmalloc.c (HAVE_GNU_MALLOC, HAVE_GNU_REALLOC): New constants.
+	(xmalloc): Suppress unnecessary check if HAVE_GNU_MALLOC.
+	(xrealloc): Suppress unnecssary check if HAVE_GNU_REALLOC.
+
 2020-05-11  Paul Eggert  <egg...@cs.ucla.edu>
 
 	careadlinkat: fix GCC 10 workaround
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
index 486873602..69c4e7dfa 100644
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -24,14 +24,26 @@
 #include <stdlib.h>
 #include <string.h>
 
-/* 1 if calloc is known to be compatible with GNU calloc.  This
-   matters if we are not also using the calloc module, which defines
-   HAVE_CALLOC_GNU and supports the GNU API even on non-GNU platforms.  */
+/* 1 if calloc, malloc and realloc are known to be compatible with GNU.
+   This matters if we are not also using the calloc-gnu, malloc-gnu
+   and realloc-gnu modules, which define HAVE_CALLOC_GNU,
+   HAVE_MALLOC_GNU and HAVE_REALLOC_GNU and support the GNU API even
+   on non-GNU platforms.  */
 #if defined HAVE_CALLOC_GNU || (defined __GLIBC__ && !defined __UCLIBC__)
 enum { HAVE_GNU_CALLOC = 1 };
 #else
 enum { HAVE_GNU_CALLOC = 0 };
 #endif
+#if defined HAVE_MALLOC_GNU || (defined __GLIBC__ && !defined __UCLIBC__)
+enum { HAVE_GNU_MALLOC = 1 };
+#else
+enum { HAVE_GNU_MALLOC = 0 };
+#endif
+#if defined HAVE_REALLOC_GNU || (defined __GLIBC__ && !defined __UCLIBC__)
+enum { HAVE_GNU_REALLOC = 1 };
+#else
+enum { HAVE_GNU_REALLOC = 0 };
+#endif
 
 /* Allocate N bytes of memory dynamically, with error checking.  */
 
@@ -39,7 +51,7 @@ void *
 xmalloc (size_t n)
 {
   void *p = malloc (n);
-  if (!p && n != 0)
+  if (!p && (HAVE_GNU_MALLOC || n))
     xalloc_die ();
   return p;
 }
@@ -50,18 +62,17 @@ xmalloc (size_t n)
 void *
 xrealloc (void *p, size_t n)
 {
-  if (!n && p)
+  if (!HAVE_GNU_REALLOC && !n && p)
     {
-      /* The GNU and C99 realloc behaviors disagree here.  Act like
-         GNU, even if the underlying realloc is C99.  */
+      /* The GNU and C99 realloc behaviors disagree here.  Act like GNU.  */
       free (p);
       return NULL;
     }
 
-  p = realloc (p, n);
-  if (!p && n)
+  void *r = realloc (p, n);
+  if (!r && (n || (HAVE_GNU_REALLOC && !p)))
     xalloc_die ();
-  return p;
+  return r;
 }
 
 /* If P is null, allocate a block of at least *PN bytes; otherwise,
-- 
2.17.1

Reply via email to