bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] xalloc: no attribute (malloc (free)) on inline


From: Paul Eggert
Subject: [PATCH] xalloc: no attribute (malloc (free)) on inline
Date: Sun, 1 Aug 2021 22:29:04 -0700

The GCC manual says you can’t use __attribute__ ((__malloc__
(free, 1))) on inline functions.  Problem discovered when
compiling diffutils 3.8 on RHEL 8.4 using a GCC 11.2.0 that I
built myself.  Perhaps the problem was not discovered earlier
because the attribute works with ‘free’ (which is what I was
seeing before on Fedora 34) but not with ‘rpl_free’ (seen on RHEL
8.4).  Anyway, the GCC manual says it shouldn’t work at all, so
don’t use it.
* lib/xalloc.h (xnmalloc, xcharalloc): No longer inline.
* lib/xmalloc.c (xcharalloc, xnmalloc): Move function bodies here.
* m4/gnulib-common.m4 (_GL_ATTRIBUTE_DEALLOC)
(_GL_ATTRIBUTE_DEALLOC_FREE): Document that these cannot be
used on inline functions, as per the GCC 11.2.1 manual.
---
 ChangeLog           | 15 +++++++++++++++
 lib/xalloc.h        | 14 ++------------
 lib/xmalloc.c       | 15 +++++++++++++++
 m4/gnulib-common.m4 |  3 ++-
 4 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f908d4ef5..98fef6c6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2021-08-01  Paul Eggert  <eggert@cs.ucla.edu>
 
+       xalloc: no attribute (malloc (free)) on inline
+       The GCC manual says you can’t use __attribute__ ((__malloc__
+       (free, 1))) on inline functions.  Problem discovered when
+       compiling diffutils 3.8 on RHEL 8.4 using a GCC 11.2.0 that I
+       built myself.  Perhaps the problem was not discovered earlier
+       because the attribute works with ‘free’ (which is what I was
+       seeing before on Fedora 34) but not with ‘rpl_free’ (seen on RHEL
+       8.4).  Anyway, the GCC manual says it shouldn’t work at all, so
+       don’t use it.
+       * lib/xalloc.h (xnmalloc, xcharalloc): No longer inline.
+       * lib/xmalloc.c (xcharalloc, xnmalloc): Move function bodies here.
+       * m4/gnulib-common.m4 (_GL_ATTRIBUTE_DEALLOC)
+       (_GL_ATTRIBUTE_DEALLOC_FREE): Document that these cannot be
+       used on inline functions, as per the GCC 11.2.1 manual.
+
        sigsegv-tests: make more things static
        * tests/test-sigsegv-catch-segv1.c:
        * tests/test-sigsegv-catch-stackoverflow1.c:
diff --git a/lib/xalloc.h b/lib/xalloc.h
index 05e2daa71..ee07113fe 100644
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
@@ -128,14 +128,9 @@ char *xstrdup (char const *str)
 /* Allocate an array of N objects, each with S bytes of memory,
    dynamically, with error checking.  S must be nonzero.  */
 
-XALLOC_INLINE void *xnmalloc (size_t n, size_t s)
+void *xnmalloc (size_t n, size_t s)
   _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
   _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL;
-XALLOC_INLINE void *
-xnmalloc (size_t n, size_t s)
-{
-  return xreallocarray (NULL, n, s);
-}
 
 /* FIXME: Deprecate this in favor of xreallocarray?  */
 /* Change the size of an allocated block of memory P to an array of N
@@ -152,14 +147,9 @@ xnrealloc (void *p, size_t n, size_t s)
 /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
    except it returns char *.  */
 
-XALLOC_INLINE char *xcharalloc (size_t n)
+char *xcharalloc (size_t n)
   _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
   _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL;
-XALLOC_INLINE char *
-xcharalloc (size_t n)
-{
-  return XNMALLOC (n, char);
-}
 
 #endif /* GNULIB_XALLOC */
 
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
index 81bb427d3..51a0832de 100644
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -50,6 +50,12 @@ ximalloc (idx_t s)
   return nonnull (imalloc (s));
 }
 
+char *
+xcharalloc (size_t n)
+{
+  return XNMALLOC (n, char);
+}
+
 /* Change the size of an allocated block of memory P to S bytes,
    with error checking.  */
 
@@ -86,6 +92,15 @@ xireallocarray (void *p, idx_t n, idx_t s)
   return nonnull (ireallocarray (p, n, s));
 }
 
+/* Allocate an array of N objects, each with S bytes of memory,
+   dynamically, with error checking.  S must be nonzero.  */
+
+void *
+xnmalloc (size_t n, size_t s)
+{
+  return xreallocarray (NULL, n, s);
+}
+
 /* If P is null, allocate a block of at least *PS bytes; otherwise,
    reallocate P so that it contains more than *PS bytes.  *PS must be
    nonzero unless P is null.  Set *PS to the new block's size, and
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index 2872ecdf7..ddbc7b773 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -152,7 +152,8 @@ AC_DEFUN([gl_COMMON_BODY], [
    that can be freed by passing them as the Ith argument to the
    function F.  _GL_ATTRIBUTE_DEALLOC_FREE is for functions that
    return pointers that can be freed via 'free'; it can be used
-   only after including stdlib.h.  */
+   only after including stdlib.h.  These macros cannot be used on
+   inline functions.  */
 #if _GL_GNUC_PREREQ (11, 0)
 # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
 #else
-- 
2.31.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]