1 /* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
2 /* { dg-enable-nn-line-numbers "" } */
3 
4 #include <stdlib.h>
5 
6 extern int some_condition ();
7 extern void do_stuff (int);
8 
9 void
may_call_free(void * victim)10 may_call_free (void *victim)
11 {
12   if (some_condition ())
13     return;
14 
15   free (victim); /* { dg-warning "double-'free' of 'victim'" } */
16 }
17 
test(void * ptr)18 void test (void *ptr)
19 {
20   do_stuff (1);
21 
22   may_call_free (ptr);
23 
24   do_stuff (2);
25 
26   may_call_free (ptr);
27 
28   do_stuff (3);
29 }
30 
31 /* { dg-begin-multiline-output "" }
32    NN |   free (victim);
33       |   ^~~~~~~~~~~~~
34   'test': events 1-2
35     |
36     |   NN | void test (void *ptr)
37     |      |      ^~~~
38     |      |      |
39     |      |      (1) entry to 'test'
40     |......
41     |   NN |   may_call_free (ptr);
42     |      |   ~~~~~~~~~~~~~~~~~~~
43     |      |   |
44     |      |   (2) calling 'may_call_free' from 'test'
45     |
46     +--> 'may_call_free': events 3-6
47            |
48            |   NN | may_call_free (void *victim)
49            |      | ^~~~~~~~~~~~~
50            |      | |
51            |      | (3) entry to 'may_call_free'
52            |   NN | {
53            |   NN |   if (some_condition ())
54            |      |      ~
55            |      |      |
56            |      |      (4) following 'false' branch...
57            |......
58            |   NN |   free (victim);
59            |      |   ~~~~~~~~~~~~~
60            |      |   |
61            |      |   (5) ...to here
62            |      |   (6) first 'free' here
63            |
64     <------+
65     |
66   'test': events 7-8
67     |
68     |   NN |   may_call_free (ptr);
69     |      |   ^~~~~~~~~~~~~~~~~~~
70     |      |   |
71     |      |   (7) returning to 'test' from 'may_call_free'
72     |......
73     |   NN |   may_call_free (ptr);
74     |      |   ~~~~~~~~~~~~~~~~~~~
75     |      |   |
76     |      |   (8) passing freed pointer 'ptr' in call to 'may_call_free' from 'test'
77     |
78     +--> 'may_call_free': events 9-12
79            |
80            |   NN | may_call_free (void *victim)
81            |      | ^~~~~~~~~~~~~
82            |      | |
83            |      | (9) entry to 'may_call_free'
84            |   NN | {
85            |   NN |   if (some_condition ())
86            |      |      ~
87            |      |      |
88            |      |      (10) following 'false' branch...
89            |......
90            |   NN |   free (victim);
91            |      |   ~~~~~~~~~~~~~
92            |      |   |
93            |      |   (11) ...to here
94            |      |   (12) second 'free' here; first 'free' was at (6)
95            |
96   { dg-end-multiline-output "" } */
97