exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / ialloc.h
blob2aa94ae7caf93f7df3cc21d432b248afad3e3f4f
1 /* ialloc.h -- malloc with idx_t rather than size_t
3 Copyright 2021-2024 Free Software Foundation, Inc.
5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
10 This file is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 #ifndef IALLOC_H_
19 #define IALLOC_H_
21 /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _GL_ATTRIBUTE_COLD,
22 _GL_ATTRIBUTE_MALLOC. */
23 #if !_GL_CONFIG_H_INCLUDED
24 #error "Please include config.h first."
25 #endif
27 #include "idx.h"
29 #include <errno.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #if defined __CHERI_PURE_CAPABILITY__
33 # include <cheri.h>
34 #endif
36 _GL_INLINE_HEADER_BEGIN
37 #ifndef IALLOC_INLINE
38 # define IALLOC_INLINE _GL_INLINE
39 #endif
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
45 IALLOC_INLINE void * _GL_ATTRIBUTE_COLD
46 _gl_alloc_nomem (void)
48 errno = ENOMEM;
49 return NULL;
52 /* imalloc (size) is like malloc (size).
53 It returns a non-NULL pointer to size bytes of memory.
54 Upon failure, it returns NULL with errno set. */
55 IALLOC_INLINE
56 _GL_ATTRIBUTE_MALLOC /*_GL_ATTRIBUTE_DEALLOC_FREE*/
57 void *
58 imalloc (idx_t s)
60 return s <= SIZE_MAX ? malloc (s) : _gl_alloc_nomem ();
63 /* irealloc (ptr, size) is like realloc (ptr, size).
64 It returns a non-NULL pointer to size bytes of memory.
65 Upon failure, it returns NULL with errno set. */
66 IALLOC_INLINE
67 /*_GL_ATTRIBUTE_DEALLOC_FREE*/
68 void *
69 irealloc (void *p, idx_t s)
71 if (s <= SIZE_MAX)
73 /* Work around GNU realloc glitch by treating a zero size as if it
74 were 1, so that returning NULL is equivalent to failing. */
75 p = realloc (p, s | !s);
76 #if defined __CHERI_PURE_CAPABILITY__
77 if (p != NULL)
78 p = cheri_bounds_set (p, s);
79 #endif
80 return p;
82 else
83 return _gl_alloc_nomem ();
86 /* icalloc (num, size) is like calloc (num, size).
87 It returns a non-NULL pointer to num * size bytes of memory.
88 Upon failure, it returns NULL with errno set. */
89 IALLOC_INLINE
90 _GL_ATTRIBUTE_MALLOC /*_GL_ATTRIBUTE_DEALLOC_FREE*/
91 void *
92 icalloc (idx_t n, idx_t s)
94 if (SIZE_MAX < n)
96 if (s != 0)
97 return _gl_alloc_nomem ();
98 n = 0;
100 if (SIZE_MAX < s)
102 if (n != 0)
103 return _gl_alloc_nomem ();
104 s = 0;
106 return calloc (n, s);
109 /* ireallocarray (ptr, num, size) is like reallocarray (ptr, num, size).
110 It returns a non-NULL pointer to num * size bytes of memory.
111 Upon failure, it returns NULL with errno set. */
112 IALLOC_INLINE void *
113 ireallocarray (void *p, idx_t n, idx_t s)
115 if (n <= SIZE_MAX && s <= SIZE_MAX)
117 /* Work around GNU reallocarray glitch by treating a zero size as if
118 it were 1, so that returning NULL is equivalent to failing. */
119 size_t nx = n;
120 size_t sx = s;
121 if (n == 0 || s == 0)
122 nx = sx = 1;
123 p = reallocarray (p, nx, sx);
124 #if defined __CHERI_PURE_CAPABILITY__
125 if (p != NULL && (n == 0 || s == 0))
126 p = cheri_bounds_set (p, 0);
127 #endif
128 return p;
130 else
131 return _gl_alloc_nomem ();
134 #ifdef __cplusplus
136 #endif
138 _GL_INLINE_HEADER_END
140 #endif