X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=lib%2Fxalloc.h;h=c419a2de6c1d574e7e810875ad44e0e63e0a326b;hb=92249085071a973e2c0621b0415b93d2e48bb00d;hp=6f5b87ee2dd8b79d3e6e37d93b3fe46b7ed3ddef;hpb=dc84183747ce1703eb99685b5dbde1f65a143c06;p=debian%2Fgzip diff --git a/lib/xalloc.h b/lib/xalloc.h index 6f5b87e..c419a2d 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -1,6 +1,6 @@ /* xalloc.h -- malloc with out-of-memory checking - Copyright (C) 1990-2000, 2003-2004, 2006-2012 Free Software Foundation, Inc. + Copyright (C) 1990-2000, 2003-2004, 2006-2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,31 +13,35 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ #ifndef XALLOC_H_ -# define XALLOC_H_ +#define XALLOC_H_ -# include +#include +#include -# include "xalloc-oversized.h" +#include "xalloc-oversized.h" -# ifdef __cplusplus -extern "C" { -# endif +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef XALLOC_INLINE +# define XALLOC_INLINE _GL_INLINE +#endif +#ifdef __cplusplus +extern "C" { +#endif -# if __GNUC__ >= 3 -# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) -# else -# define _GL_ATTRIBUTE_MALLOC -# endif -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) -# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) -# else -# define _GL_ATTRIBUTE_ALLOC_SIZE(args) -# endif +#if ! defined __clang__ && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) +#else +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) +#endif /* This function is always triggered when memory is exhausted. It must be defined by the application, either explicitly @@ -56,7 +60,7 @@ void *xrealloc (void *p, size_t s) _GL_ATTRIBUTE_ALLOC_SIZE ((2)); void *x2realloc (void *p, size_t *pn); void *xmemdup (void const *p, size_t s) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((2)); + _GL_ATTRIBUTE_ALLOC_SIZE ((2)); char *xstrdup (char const *str) _GL_ATTRIBUTE_MALLOC; @@ -67,45 +71,31 @@ char *xstrdup (char const *str) /* Allocate an object of type T dynamically, with error checking. */ /* extern t *XMALLOC (typename t); */ -# define XMALLOC(t) ((t *) xmalloc (sizeof (t))) +#define XMALLOC(t) ((t *) xmalloc (sizeof (t))) /* Allocate memory for N elements of type T, with error checking. */ /* extern t *XNMALLOC (size_t n, typename t); */ -# define XNMALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) +#define XNMALLOC(n, t) \ + ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) /* Allocate an object of type T dynamically, with error checking, and zero it. */ /* extern t *XZALLOC (typename t); */ -# define XZALLOC(t) ((t *) xzalloc (sizeof (t))) +#define XZALLOC(t) ((t *) xzalloc (sizeof (t))) /* Allocate memory for N elements of type T, with error checking, and zero it. */ /* extern t *XCALLOC (size_t n, typename t); */ -# define XCALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) +#define XCALLOC(n, t) \ + ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) -# if HAVE_INLINE -# define static_inline static inline -# else -void *xnmalloc (size_t n, size_t s) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); -void *xnrealloc (void *p, size_t n, size_t s) - _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); -void *x2nrealloc (void *p, size_t *pn, size_t s); -char *xcharalloc (size_t n) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); -# endif - -# ifdef static_inline - /* Allocate an array of N objects, each with S bytes of memory, dynamically, with error checking. S must be nonzero. */ -static_inline void *xnmalloc (size_t n, size_t s) +XALLOC_INLINE void *xnmalloc (size_t n, size_t s) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); -static_inline void * +XALLOC_INLINE void * xnmalloc (size_t n, size_t s) { if (xalloc_oversized (n, s)) @@ -116,9 +106,9 @@ xnmalloc (size_t n, size_t s) /* Change the size of an allocated block of memory P to an array of N objects each of S bytes, with error checking. S must be nonzero. */ -static_inline void *xnrealloc (void *p, size_t n, size_t s) +XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s) _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); -static_inline void * +XALLOC_INLINE void * xnrealloc (void *p, size_t n, size_t s) { if (xalloc_oversized (n, s)) @@ -128,10 +118,9 @@ xnrealloc (void *p, size_t n, size_t s) /* If P is null, allocate a block of at least *PN such objects; otherwise, reallocate P so that it contains more than *PN objects - each of S bytes. *PN must be nonzero unless P is null, and S must - be nonzero. Set *PN to the new number of objects, and return the - pointer to the new block. *PN is never set to zero, and the - returned pointer is never null. + each of S bytes. S must be nonzero. Set *PN to the new number of + objects, and return the pointer to the new block. *PN is never set + to zero, and the returned pointer is never null. Repeated reallocations are guaranteed to make progress, either by allocating an initial block with a nonzero size, or by allocating a @@ -181,7 +170,7 @@ xnrealloc (void *p, size_t n, size_t s) */ -static_inline void * +XALLOC_INLINE void * x2nrealloc (void *p, size_t *pn, size_t s) { size_t n = *pn; @@ -199,16 +188,19 @@ x2nrealloc (void *p, size_t *pn, size_t s) n = DEFAULT_MXFAST / s; n += !n; } + if (xalloc_oversized (n, s)) + xalloc_die (); } else { - /* Set N = ceil (1.5 * N) so that progress is made if N == 1. - Check for overflow, so that N * S stays in size_t range. - The check is slightly conservative, but an exact check isn't - worth the trouble. */ - if ((size_t) -1 / 3 * 2 / s <= n) + /* Set N = floor (1.5 * N) + 1 so that progress is made even if N == 0. + Check for overflow, so that N * S stays in both ptrdiff_t and + size_t range. The check may be slightly conservative, but an + exact check isn't worth the trouble. */ + if ((PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX) / 3 * 2 / s + <= n) xalloc_die (); - n += (n + 1) / 2; + n += n / 2 + 1; } *pn = n; @@ -218,17 +210,15 @@ x2nrealloc (void *p, size_t *pn, size_t s) /* Return a pointer to a new buffer of N bytes. This is like xmalloc, except it returns char *. */ -static_inline char *xcharalloc (size_t n) +XALLOC_INLINE char *xcharalloc (size_t n) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); -static_inline char * +XALLOC_INLINE char * xcharalloc (size_t n) { return XNMALLOC (n, char); } -# endif - -# ifdef __cplusplus +#ifdef __cplusplus } /* C++ does not allow conversions from void * to other pointer types @@ -265,7 +255,8 @@ xmemdup (T const *p, size_t s) return (T *) xmemdup ((void const *) p, s); } -# endif +#endif +_GL_INLINE_HEADER_END #endif /* !XALLOC_H_ */