Skip to content

Commit 663cc70

Browse files
committed
Suppress xmalloc warnings
The latest GCC produces incorrect warnings about using the pointer passed to realloc and reallocarray when the functions return NULL. Suppress that warning, and change the call syntax for the error handler to avoid tickling a bug in clang-format.
1 parent d5d7ac1 commit 663cc70

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ rra-c-util 10.5 (unreleased)
1111
temporary files generated by tests when checking for SPDX licenses and
1212
Perl strictness in standard tests.
1313

14+
Suppress erroneous warnings from GCC 13.2 for xrealloc and
15+
xreallocarray.
16+
1417
rra-c-util 10.4 (2023-03-31)
1518

1619
Add serial numbers to every Autoconf macro provided by this package.

util/xmalloc.c

+45-12
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
* which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
6464
*
6565
* Written by Russ Allbery <[email protected]>
66-
* Copyright 2015 Russ Allbery <[email protected]>
66+
* Copyright 2015, 2023 Russ Allbery <[email protected]>
6767
* Copyright 2012-2014
6868
* The Board of Trustees of the Leland Stanford Junior University
6969
* Copyright 2004-2006 Internet Systems Consortium, Inc. ("ISC")
@@ -121,7 +121,7 @@ x_malloc(size_t size, const char *file, int line)
121121
real_size = (size > 0) ? size : 1;
122122
p = malloc(real_size);
123123
while (p == NULL) {
124-
(*xmalloc_error_handler)("malloc", size, file, line);
124+
xmalloc_error_handler("malloc", size, file, line);
125125
p = malloc(real_size);
126126
}
127127
return p;
@@ -137,7 +137,7 @@ x_calloc(size_t n, size_t size, const char *file, int line)
137137
size = (size > 0) ? size : 1;
138138
p = calloc(n, size);
139139
while (p == NULL) {
140-
(*xmalloc_error_handler)("calloc", n * size, file, line);
140+
xmalloc_error_handler("calloc", n * size, file, line);
141141
p = calloc(n, size);
142142
}
143143
return p;
@@ -150,11 +150,27 @@ x_realloc(void *p, size_t size, const char *file, int line)
150150
void *newp;
151151

152152
newp = realloc(p, size);
153-
while (newp == NULL && size > 0) {
154-
(*xmalloc_error_handler)("realloc", size, file, line);
153+
if (size == 0)
154+
return newp;
155+
156+
/*
157+
* GCC 13.2.0 (and some earlier versions) misdiagnose this error
158+
* handling as a use-after-free of p, but the C standard guarantees
159+
* that if realloc fails (which is true in every case when it returns
160+
* NULL when size > 0), p is unchanged and still valid.
161+
*/
162+
#if __GNUC__ >= 12 && !defined(__clang__)
163+
# pragma GCC diagnostic push
164+
# pragma GCC diagnostic ignored "-Wuse-after-free"
165+
#endif
166+
while (newp == NULL) {
167+
xmalloc_error_handler("realloc", size, file, line);
155168
newp = realloc(p, size);
156169
}
157170
return newp;
171+
#if __GNUC__ >= 12 && !defined(__clang__)
172+
# pragma GCC diagnostic pop
173+
#endif
158174
}
159175

160176

@@ -164,10 +180,27 @@ x_reallocarray(void *p, size_t n, size_t size, const char *file, int line)
164180
void *newp;
165181

166182
newp = reallocarray(p, n, size);
167-
while (newp == NULL && size > 0 && n > 0) {
168-
(*xmalloc_error_handler)("reallocarray", n * size, file, line);
183+
if (size == 0 || n == 0)
184+
return newp;
185+
186+
/*
187+
* GCC 13.2.0 (and some earlier versions) misdiagnose this error
188+
* handling as a use-after-free of p, but the documentation of
189+
* reallocarray guarantees that if reallocarray fails (which is true in
190+
* every case when it returns NULL when size > 0 and n > 0), p is
191+
* unchanged and still valid.
192+
*/
193+
#if __GNUC__ >= 12 && !defined(__clang__)
194+
# pragma GCC diagnostic push
195+
# pragma GCC diagnostic ignored "-Wuse-after-free"
196+
#endif
197+
while (newp == NULL) {
198+
xmalloc_error_handler("reallocarray", n * size, file, line);
169199
newp = reallocarray(p, n, size);
170200
}
201+
#if __GNUC__ >= 12 && !defined(__clang__)
202+
# pragma GCC diagnostic pop
203+
#endif
171204
return newp;
172205
}
173206

@@ -181,7 +214,7 @@ x_strdup(const char *s, const char *file, int line)
181214
len = strlen(s) + 1;
182215
p = malloc(len);
183216
while (p == NULL) {
184-
(*xmalloc_error_handler)("strdup", len, file, line);
217+
xmalloc_error_handler("strdup", len, file, line);
185218
p = malloc(len);
186219
}
187220
memcpy(p, s, len);
@@ -207,7 +240,7 @@ x_strndup(const char *s, size_t size, const char *file, int line)
207240
length = p - s;
208241
copy = malloc(length + 1);
209242
while (copy == NULL) {
210-
(*xmalloc_error_handler)("strndup", length + 1, file, line);
243+
xmalloc_error_handler("strndup", length + 1, file, line);
211244
copy = malloc(length + 1);
212245
}
213246
memcpy(copy, s, length);
@@ -231,7 +264,7 @@ x_vasprintf(char **strp, const char *fmt, va_list args, const char *file,
231264
status = vsnprintf(NULL, 0, fmt, args_copy);
232265
va_end(args_copy);
233266
status = (status < 0) ? 0 : status + 1;
234-
(*xmalloc_error_handler)("vasprintf", status, file, line);
267+
xmalloc_error_handler("vasprintf", status, file, line);
235268
va_copy(args_copy, args);
236269
status = vasprintf(strp, fmt, args_copy);
237270
va_end(args_copy);
@@ -255,7 +288,7 @@ x_asprintf(char **strp, const char *file, int line, const char *fmt, ...)
255288
status = vsnprintf(NULL, 0, fmt, args_copy);
256289
va_end(args_copy);
257290
status = (status < 0) ? 0 : status + 1;
258-
(*xmalloc_error_handler)("asprintf", status, file, line);
291+
xmalloc_error_handler("asprintf", status, file, line);
259292
va_copy(args_copy, args);
260293
status = vasprintf(strp, fmt, args_copy);
261294
va_end(args_copy);
@@ -278,7 +311,7 @@ x_asprintf(char **strp, const char *fmt, ...)
278311
status = vsnprintf(NULL, 0, fmt, args_copy);
279312
va_end(args_copy);
280313
status = (status < 0) ? 0 : status + 1;
281-
(*xmalloc_error_handler)("asprintf", status, __FILE__, __LINE__);
314+
xmalloc_error_handler("asprintf", status, __FILE__, __LINE__);
282315
va_copy(args_copy, args);
283316
status = vasprintf(strp, fmt, args_copy);
284317
va_end(args_copy);

0 commit comments

Comments
 (0)