Make use of GCC's attribute __alloc_size__.
[gnulib.git] / lib / xalloc.h
1 /* xalloc.h -- malloc with out-of-memory checking
2
3    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4    2000, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
5    Inc.
6
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #ifndef XALLOC_H_
21 # define XALLOC_H_
22
23 # include <stddef.h>
24
25
26 # ifdef __cplusplus
27 extern "C" {
28 # endif
29
30
31 # ifndef __attribute__
32 #  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
33 #   define __attribute__(x)
34 #  endif
35 # endif
36
37 # ifndef ATTRIBUTE_NORETURN
38 #  define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
39 # endif
40
41 # ifndef ATTRIBUTE_MALLOC
42 #  if __GNUC__ >= 3
43 #   define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
44 #  else
45 #   define ATTRIBUTE_MALLOC
46 #  endif
47 # endif
48
49 # ifndef ATTRIBUTE_ALLOC_SIZE
50 #  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
51 #   define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
52 #  else
53 #   define ATTRIBUTE_ALLOC_SIZE(args)
54 #  endif
55 # endif
56
57 /* This function is always triggered when memory is exhausted.
58    It must be defined by the application, either explicitly
59    or by using gnulib's xalloc-die module.  This is the
60    function to call when one wants the program to die because of a
61    memory allocation failure.  */
62 extern void xalloc_die (void) ATTRIBUTE_NORETURN;
63
64 void *xmalloc (size_t s)
65       ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
66 void *xzalloc (size_t s)
67       ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
68 void *xcalloc (size_t n, size_t s)
69       ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1, 2));
70 void *xrealloc (void *p, size_t s)
71       ATTRIBUTE_ALLOC_SIZE ((2));
72 void *x2realloc (void *p, size_t *pn);
73 void *xmemdup (void const *p, size_t s)
74       ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((2));
75 char *xstrdup (char const *str)
76       ATTRIBUTE_MALLOC;
77
78 /* Return 1 if an array of N objects, each of size S, cannot exist due
79    to size arithmetic overflow.  S must be positive and N must be
80    nonnegative.  This is a macro, not an inline function, so that it
81    works correctly even when SIZE_MAX < N.
82
83    By gnulib convention, SIZE_MAX represents overflow in size
84    calculations, so the conservative dividend to use here is
85    SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
86    However, malloc (SIZE_MAX) fails on all known hosts where
87    sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
88    exactly-SIZE_MAX allocations on such hosts; this avoids a test and
89    branch when S is known to be 1.  */
90 # define xalloc_oversized(n, s) \
91     ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
92
93
94 /* In the following macros, T must be an elementary or structure/union or
95    typedef'ed type, or a pointer to such a type.  To apply one of the
96    following macros to a function pointer or array type, you need to typedef
97    it first and use the typedef name.  */
98
99 /* Allocate an object of type T dynamically, with error checking.  */
100 /* extern t *XMALLOC (typename t); */
101 # define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
102
103 /* Allocate memory for N elements of type T, with error checking.  */
104 /* extern t *XNMALLOC (size_t n, typename t); */
105 # define XNMALLOC(n, t) \
106     ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
107
108 /* Allocate an object of type T dynamically, with error checking,
109    and zero it.  */
110 /* extern t *XZALLOC (typename t); */
111 # define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
112
113 /* Allocate memory for N elements of type T, with error checking,
114    and zero it.  */
115 /* extern t *XCALLOC (size_t n, typename t); */
116 # define XCALLOC(n, t) \
117     ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
118
119
120 # if HAVE_INLINE
121 #  define static_inline static inline
122 # else
123 void *xnmalloc (size_t n, size_t s)
124       ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1, 2));
125 void *xnrealloc (void *p, size_t n, size_t s)
126       ATTRIBUTE_ALLOC_SIZE ((2, 3));
127 void *x2nrealloc (void *p, size_t *pn, size_t s);
128 char *xcharalloc (size_t n)
129       ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
130 # endif
131
132 # ifdef static_inline
133
134 /* Allocate an array of N objects, each with S bytes of memory,
135    dynamically, with error checking.  S must be nonzero.  */
136
137 static_inline void *xnmalloc (size_t n, size_t s)
138                     ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1, 2));
139 static_inline void *
140 xnmalloc (size_t n, size_t s)
141 {
142   if (xalloc_oversized (n, s))
143     xalloc_die ();
144   return xmalloc (n * s);
145 }
146
147 /* Change the size of an allocated block of memory P to an array of N
148    objects each of S bytes, with error checking.  S must be nonzero.  */
149
150 static_inline void *xnrealloc (void *p, size_t n, size_t s)
151                     ATTRIBUTE_ALLOC_SIZE ((2, 3));
152 static_inline void *
153 xnrealloc (void *p, size_t n, size_t s)
154 {
155   if (xalloc_oversized (n, s))
156     xalloc_die ();
157   return xrealloc (p, n * s);
158 }
159
160 /* If P is null, allocate a block of at least *PN such objects;
161    otherwise, reallocate P so that it contains more than *PN objects
162    each of S bytes.  *PN must be nonzero unless P is null, and S must
163    be nonzero.  Set *PN to the new number of objects, and return the
164    pointer to the new block.  *PN is never set to zero, and the
165    returned pointer is never null.
166
167    Repeated reallocations are guaranteed to make progress, either by
168    allocating an initial block with a nonzero size, or by allocating a
169    larger block.
170
171    In the following implementation, nonzero sizes are increased by a
172    factor of approximately 1.5 so that repeated reallocations have
173    O(N) overall cost rather than O(N**2) cost, but the
174    specification for this function does not guarantee that rate.
175
176    Here is an example of use:
177
178      int *p = NULL;
179      size_t used = 0;
180      size_t allocated = 0;
181
182      void
183      append_int (int value)
184        {
185          if (used == allocated)
186            p = x2nrealloc (p, &allocated, sizeof *p);
187          p[used++] = value;
188        }
189
190    This causes x2nrealloc to allocate a block of some nonzero size the
191    first time it is called.
192
193    To have finer-grained control over the initial size, set *PN to a
194    nonzero value before calling this function with P == NULL.  For
195    example:
196
197      int *p = NULL;
198      size_t used = 0;
199      size_t allocated = 0;
200      size_t allocated1 = 1000;
201
202      void
203      append_int (int value)
204        {
205          if (used == allocated)
206            {
207              p = x2nrealloc (p, &allocated1, sizeof *p);
208              allocated = allocated1;
209            }
210          p[used++] = value;
211        }
212
213    */
214
215 static_inline void *
216 x2nrealloc (void *p, size_t *pn, size_t s)
217 {
218   size_t n = *pn;
219
220   if (! p)
221     {
222       if (! n)
223         {
224           /* The approximate size to use for initial small allocation
225              requests, when the invoking code specifies an old size of
226              zero.  64 bytes is the largest "small" request for the
227              GNU C library malloc.  */
228           enum { DEFAULT_MXFAST = 64 };
229
230           n = DEFAULT_MXFAST / s;
231           n += !n;
232         }
233     }
234   else
235     {
236       /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
237          Check for overflow, so that N * S stays in size_t range.
238          The check is slightly conservative, but an exact check isn't
239          worth the trouble.  */
240       if ((size_t) -1 / 3 * 2 / s <= n)
241         xalloc_die ();
242       n += (n + 1) / 2;
243     }
244
245   *pn = n;
246   return xrealloc (p, n * s);
247 }
248
249 /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
250    except it returns char *.  */
251
252 static_inline char *xcharalloc (size_t n)
253                     ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE ((1));
254 static_inline char *
255 xcharalloc (size_t n)
256 {
257   return XNMALLOC (n, char);
258 }
259
260 # endif
261
262 # ifdef __cplusplus
263 }
264
265 /* C++ does not allow conversions from void * to other pointer types
266    without a cast.  Use templates to work around the problem when
267    possible.  */
268
269 template <typename T> inline T *
270 xrealloc (T *p, size_t s)
271 {
272   return (T *) xrealloc ((void *) p, s);
273 }
274
275 template <typename T> inline T *
276 xnrealloc (T *p, size_t n, size_t s)
277 {
278   return (T *) xnrealloc ((void *) p, n, s);
279 }
280
281 template <typename T> inline T *
282 x2realloc (T *p, size_t *pn)
283 {
284   return (T *) x2realloc ((void *) p, pn);
285 }
286
287 template <typename T> inline T *
288 x2nrealloc (T *p, size_t *pn, size_t s)
289 {
290   return (T *) x2nrealloc ((void *) p, pn, s);
291 }
292
293 template <typename T> inline T *
294 xmemdup (T const *p, size_t s)
295 {
296   return (T *) xmemdup ((void const *) p, s);
297 }
298
299 # endif
300
301
302 #endif /* !XALLOC_H_ */