openat: don’t close (-1)
[gnulib.git] / lib / realloc.c
blob58044745f458678753c30a4194a8232a6c205720
1 /* realloc() function that is glibc compatible.
3 Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2024 Free Software
4 Foundation, Inc.
6 This file is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 This file is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
19 /* written by Jim Meyering and Bruno Haible */
21 /* Ensure that we call the system's realloc() below. */
22 #define _GL_USE_STDLIB_ALLOC 1
23 #include <config.h>
25 #define _GL_REALLOC_INLINE _GL_EXTERN_INLINE
26 #include <stdlib.h>
28 #include <errno.h>
29 #include <stdckdint.h>
31 #ifdef __CHERI_PURE_CAPABILITY__
32 # include <cheri.h>
33 #endif
35 #ifndef _GL_INLINE_RPL_REALLOC
37 /* Change the size of an allocated block of memory P to N bytes,
38 with error checking. If P is NULL, use malloc. Otherwise if N is zero,
39 free P and return NULL. */
41 void *
42 rpl_realloc (void *p, size_t n)
44 size_t n1 = n;
46 if (n == 0)
48 # if NEED_SANITIZED_REALLOC
49 /* When P is non-null, ISO C23 §7.24.3.7.(3) says realloc (P, 0) has
50 undefined behavior even though C17 and earlier partially defined
51 the behavior. Let the programmer know.
52 When the undefined-behaviour sanitizers report this case, i.e. when
53 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117233> and
54 <https://github.com/llvm/llvm-project/issues/113065>
55 have been closed and new releases of GCC and clang have been made,
56 we can revisit this code. */
57 if (p != NULL)
58 abort ();
59 # endif
61 /* realloc (NULL, 0) acts like glibc malloc (0), i.e., like malloc (1)
62 except the caller cannot dereference any non-null return.
64 realloc (P, 0) with non-null P is a messier situation.
65 As mentioned above, C23 says behavior is undefined.
66 POSIX.1-2024 extends C17 to say realloc (P, 0)
67 either fails by setting errno and returning a null pointer,
68 or succeeds by freeing P and then either:
69 (a) setting errno=EINVAL and returning a null pointer; or
70 (b) acting like a successful malloc (0).
71 glibc 1 through 2.1 realloc acted like (b),
72 which conforms to C17, to C23 and to POSIX.1-2024.
73 glibc 2.1.1+ realloc acts like (a) except it does not set errno;
74 this conforms to C17 and to C23 but not to POSIX.1-2024.
75 Quite possibly future versions of POSIX will change,
76 due either to C23 or to (a)'s semantics being messy.
77 Act like (b), as that's easy, matches GNU, BSD and V7 malloc,
78 matches BSD and V7 realloc, and requires no extra code at
79 caller sites. */
81 # if !HAVE_REALLOC_0_NONNULL
82 n1 = 1;
83 # endif
86 # if !HAVE_MALLOC_PTRDIFF
87 ptrdiff_t signed_n;
88 if (ckd_add (&signed_n, n, 0))
90 errno = ENOMEM;
91 return NULL;
93 # endif
95 void *result = realloc (p, n1);
97 # if !HAVE_MALLOC_POSIX
98 if (result == NULL)
99 errno = ENOMEM;
100 # endif
102 # ifdef __CHERI_PURE_CAPABILITY__
103 if (result != NULL)
104 result = cheri_bounds_set (result, n);
105 # endif
107 return result;
110 #endif