blob: 459357cf13813e987e728c60f9f0c6cbab72d3bf [file] [log] [blame]
/* { dg-additional-options "-Wno-analyzer-too-complex" } */
/* Verify absence of false positive from -Wanalyzer-mismatching-deallocation
on realloc(3).
Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/command.c#L115
which is GPLv2 or later. */
typedef __SIZE_TYPE__ size_t;
typedef __builtin_va_list va_list;
#define NULL ((void *)0)
extern void *malloc (size_t __size)
__attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__malloc__))
__attribute__ ((__alloc_size__ (1)));
extern void perror (const char *__s);
extern void *realloc (void *__ptr, size_t __size)
__attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__warn_unused_result__))
__attribute__ ((__alloc_size__ (2)));
extern void guestfs_int_cleanup_free (void *ptr);
extern int commandrvf (char **stdoutput, char **stderror, unsigned flags,
char const* const *argv);
#define CLEANUP_FREE __attribute__((cleanup(guestfs_int_cleanup_free)))
int
commandrf (char **stdoutput, char **stderror, unsigned flags,
const char *name, ...)
{
va_list args;
CLEANUP_FREE const char **argv = NULL;
char *s;
int i, r;
/* Collect the command line arguments into an array. */
i = 2;
argv = malloc (sizeof (char *) * i);
if (argv == NULL) {
perror ("malloc");
return -1;
}
argv[0] = (char *) name;
argv[1] = NULL;
__builtin_va_start (args, name);
while ((s = __builtin_va_arg (args, char *)) != NULL) {
const char **p = realloc (argv, sizeof (char *) * (++i)); /* { dg-bogus "'free'" } */
if (p == NULL) {
perror ("realloc");
__builtin_va_end (args);
return -1;
}
argv = p;
argv[i-2] = s;
argv[i-1] = NULL;
}
__builtin_va_end (args);
r = commandrvf (stdoutput, stderror, flags, argv);
return r;
}