From: Paul Eggert Date: Mon, 2 Aug 2021 05:27:49 +0000 (-0700) Subject: xalloc: no attribute (malloc (free)) on inline X-Git-Tag: v1.0~2732 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=9b69ffb766a2f6c0a06ad4b71040209534fde094;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index f908d4ef56..98fef6c6c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2021-08-01 Paul Eggert + 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 05e2daa719..ee07113fed 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 81bb427d33..51a0832dee 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 2872ecdf77..ddbc7b7736 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