1 /* { dg-do compile } */
2 /* { dg-options "-fdiagnostics-show-caret" } */
3 
4 #include <stdlib.h>
5 
wrapped_malloc(size_t size)6 void *wrapped_malloc (size_t size)
7 {
8   return malloc (size);
9 }
10 
wrapped_free(void * ptr)11 void wrapped_free (void *ptr)
12 {
13   free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
14   /* { dg-begin-multiline-output "" }
15    free (ptr);
16    ^~~~~~~~~~
17   'test': events 1-2
18     |
19     | {
20     | ^
21     | |
22     | (1) entering 'test'
23     |   boxed_int *obj = make_boxed_int (i);
24     |                    ~~~~~~~~~~~~~~~~~~
25     |                    |
26     |                    (2) calling 'make_boxed_int'
27     |
28     +--> 'make_boxed_int': events 3-4
29            |
30            | {
31            | ^
32            | |
33            | (3) entering 'make_boxed_int'
34            |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
35            |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36            |                                    |
37            |                                    (4) calling 'wrapped_malloc'
38            |
39            +--> 'wrapped_malloc': events 5-6
40                   |
41                   | {
42                   | ^
43                   | |
44                   | (5) entering 'wrapped_malloc'
45                   |   return malloc (size);
46                   |          ~~~~~~~~~~~~~
47                   |          |
48                   |          (6) calling 'malloc'
49                   |
50     <-------------+
51     |
52   'test': event 7
53     |
54     |   free_boxed_int (obj);
55     |   ^~~~~~~~~~~~~~~~~~~~
56     |   |
57     |   (7) calling 'free_boxed_int'
58     |
59     +--> 'free_boxed_int': events 8-9
60            |
61            | {
62            | ^
63            | |
64            | (8) entering 'free_boxed_int'
65            |   wrapped_free (bi);
66            |   ~~~~~~~~~~~~~~~~~
67            |   |
68            |   (9) calling 'wrapped_free'
69            |
70            +--> 'wrapped_free': events 10-11
71                   |
72                   | {
73                   | ^
74                   | |
75                   | (10) entering 'wrapped_free'
76                   |   free (ptr);
77                   |   ~~~~~~~~~~
78                   |   |
79                   |   (11) calling 'free'
80                   |
81     <-------------+
82     |
83   'test': event 12
84     |
85     |   free_boxed_int (obj);
86     |   ^~~~~~~~~~~~~~~~~~~~
87     |   |
88     |   (12) calling 'free_boxed_int'
89     |
90     +--> 'free_boxed_int': events 13-14
91            |
92            | {
93            | ^
94            | |
95            | (13) entering 'free_boxed_int'
96            |   wrapped_free (bi);
97            |   ~~~~~~~~~~~~~~~~~
98            |   |
99            |   (14) calling 'wrapped_free'
100            |
101            +--> 'wrapped_free': events 15-16
102                   |
103                   | {
104                   | ^
105                   | |
106                   | (15) entering 'wrapped_free'
107                   |   free (ptr);
108                   |   ~~~~~~~~~~
109                   |   |
110                   |   (16) calling 'free'
111                   |
112      { dg-end-multiline-output "" } */
113 }
114 
115 typedef struct boxed_int
116 {
117   int i;
118 } boxed_int;
119 
120 boxed_int *
make_boxed_int(int i)121 make_boxed_int (int i)
122 {
123   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
124   result->i = i;
125   return result;
126 }
127 
128 void
free_boxed_int(boxed_int * bi)129 free_boxed_int (boxed_int *bi)
130 {
131   wrapped_free (bi);
132 }
133 
test(int i)134 void test (int i)
135 {
136   boxed_int *obj = make_boxed_int (i);
137 
138   free_boxed_int (obj);
139 
140   free_boxed_int (obj);
141 }
142 
143