1 /* { dg-additional-options "-Wno-analyzer-too-complex" } */
2
3 /* Verify absence of false positive from -Wanalyzer-mismatching-deallocation
4 on realloc(3).
5 Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/command.c#L115
6 which is GPLv2 or later. */
7
8 typedef __SIZE_TYPE__ size_t;
9 typedef __builtin_va_list va_list;
10
11 #define NULL ((void *)0)
12
13 extern void *malloc (size_t __size)
14 __attribute__ ((__nothrow__ , __leaf__))
15 __attribute__ ((__malloc__))
16 __attribute__ ((__alloc_size__ (1)));
17 extern void perror (const char *__s);
18 extern void *realloc (void *__ptr, size_t __size)
19 __attribute__ ((__nothrow__ , __leaf__))
20 __attribute__ ((__warn_unused_result__))
21 __attribute__ ((__alloc_size__ (2)));
22
23 extern void guestfs_int_cleanup_free (void *ptr);
24 extern int commandrvf (char **stdoutput, char **stderror, unsigned flags,
25 char const* const *argv);
26 #define CLEANUP_FREE __attribute__((cleanup(guestfs_int_cleanup_free)))
27
28 int
29 commandrf (char **stdoutput, char **stderror, unsigned flags,
30 const char *name, ...)
31 {
32 va_list args;
33 CLEANUP_FREE const char **argv = NULL;
34 char *s;
35 int i, r;
36
37 /* Collect the command line arguments into an array. */
38 i = 2;
39 argv = malloc (sizeof (char *) * i);
40
41 if (argv == NULL) {
42 perror ("malloc");
43 return -1;
44 }
45 argv[0] = (char *) name;
46 argv[1] = NULL;
47
48 __builtin_va_start (args, name);
49
50 while ((s = __builtin_va_arg (args, char *)) != NULL) {
51 const char **p = realloc (argv, sizeof (char *) * (++i)); /* { dg-bogus "'free'" } */
52 if (p == NULL) {
53 perror ("realloc");
54 __builtin_va_end (args);
55 return -1;
56 }
57 argv = p;
58 argv[i-2] = s;
59 argv[i-1] = NULL;
60 }
61
62 __builtin_va_end (args);
63
64 r = commandrvf (stdoutput, stderror, flags, argv);
65
66 return r;
67 }