1 /* Reproducer for report from -Wanalyzer-malloc-leak
2    Reduced from
3      https://git.qemu.org/?p=qemu.git;a=blob;f=subprojects/libvhost-user/libvhost-user.c;h=fab7ca17ee1fb27bcfc338527d1aeb9f923aade5;hb=HEAD#l1184
4    which is licensed under GNU GPLv2 or later. */
5 
6 typedef unsigned char uint8_t;
7 typedef unsigned short uint16_t;
8 typedef unsigned long uint64_t;
9 typedef unsigned long uint64_t;
10 typedef long unsigned int size_t;
11 
12 extern void *calloc(size_t __nmemb, size_t __size)
13   __attribute__((__nothrow__, __leaf__))
14   __attribute__((__malloc__))
15   __attribute__((__alloc_size__(1, 2)))
16   __attribute__((__warn_unused_result__));
17 
18 typedef struct VuDescStateSplit {
19   uint8_t inflight;
20   uint64_t counter;
21 } VuDescStateSplit;
22 
23 typedef struct VuVirtqInflight {
24   uint16_t desc_num;
25   VuDescStateSplit desc[];
26 } VuVirtqInflight;
27 
28 typedef struct VuVirtqInflightDesc {
29   uint16_t index;
30   uint64_t counter;
31 } VuVirtqInflightDesc;
32 
33 typedef struct VuVirtq {
34   VuVirtqInflight *inflight;
35   VuVirtqInflightDesc *resubmit_list;
36   uint16_t resubmit_num;
37   uint64_t counter;
38   int inuse;
39 } VuVirtq;
40 
vu_check_queue_inflights(VuVirtq * vq)41 int vu_check_queue_inflights(VuVirtq *vq) {
42   int i = 0;
43 
44   if (vq->inuse) {
45     vq->resubmit_list = calloc(vq->inuse, sizeof(VuVirtqInflightDesc));
46     if (!vq->resubmit_list) {
47       return -1;
48     }
49 
50     for (i = 0; i < vq->inflight->desc_num; i++) {
51       if (vq->inflight->desc[i].inflight) {
52         vq->resubmit_list[vq->resubmit_num].index = i; /* { dg-bogus "leak" } */
53         vq->resubmit_list[vq->resubmit_num].counter =
54             vq->inflight->desc[i].counter;
55         vq->resubmit_num++;
56       }
57     }
58   }
59 
60   return 0;
61 }
62