| /* { 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; |
| } |