145
|
1 /* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fanalyzer-verbosity=0" } */
|
|
2 /* { dg-enable-nn-line-numbers "" } */
|
|
3
|
|
4 #include <stdlib.h>
|
|
5
|
|
6 void calls_free_1 (void *ptr)
|
|
7 {
|
|
8 free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
|
|
9 }
|
|
10
|
|
11 void test_1 (void *ptr, int a, int b)
|
|
12 {
|
|
13 if (a)
|
|
14 calls_free_1 (ptr);
|
|
15
|
|
16 if (b)
|
|
17 {
|
|
18 }
|
|
19 else
|
|
20 calls_free_1 (ptr);
|
|
21 }
|
|
22
|
|
23 /* { dg-begin-multiline-output "" }
|
|
24 NN | free (ptr);
|
|
25 | ^~~~~~~~~~
|
|
26 'test_1': event 1
|
|
27 |
|
|
28 | NN | calls_free_1 (ptr);
|
|
29 | | ^~~~~~~~~~~~~~~~~~
|
|
30 | | |
|
|
31 | | (1) calling 'calls_free_1' from 'test_1'
|
|
32 |
|
|
33 +--> 'calls_free_1': event 2
|
|
34 |
|
|
35 | NN | free (ptr);
|
|
36 | | ^~~~~~~~~~
|
|
37 | | |
|
|
38 | | (2) first 'free' here
|
|
39 |
|
|
40 <------+
|
|
41 |
|
|
42 'test_1': events 3-4
|
|
43 |
|
|
44 | NN | calls_free_1 (ptr);
|
|
45 | | ^~~~~~~~~~~~~~~~~~
|
|
46 | | |
|
|
47 | | (3) returning to 'test_1' from 'calls_free_1'
|
|
48 |......
|
|
49 | NN | calls_free_1 (ptr);
|
|
50 | | ~~~~~~~~~~~~~~~~~~
|
|
51 | | |
|
|
52 | | (4) passing freed pointer 'ptr' in call to 'calls_free_1' from 'test_1'
|
|
53 |
|
|
54 +--> 'calls_free_1': event 5
|
|
55 |
|
|
56 | NN | free (ptr);
|
|
57 | | ^~~~~~~~~~
|
|
58 | | |
|
|
59 | | (5) second 'free' here; first 'free' was at (2)
|
|
60 |
|
|
61 { dg-end-multiline-output "" } */
|
|
62
|
|
63 void calls_free_2 (void *ptr)
|
|
64 {
|
|
65 free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
|
|
66 }
|
|
67
|
|
68 void test_2 (void *ptr, int a, int b)
|
|
69 {
|
|
70 switch (a)
|
|
71 {
|
|
72 default:
|
|
73 break;
|
|
74 case 1:
|
|
75 break;
|
|
76 case 3:
|
|
77 calls_free_2 (ptr);
|
|
78 break;
|
|
79 }
|
|
80
|
|
81 switch (b)
|
|
82 {
|
|
83 default:
|
|
84 calls_free_2 (ptr);
|
|
85 break;
|
|
86 case 1:
|
|
87 break;
|
|
88 case 42:
|
|
89 break;
|
|
90 }
|
|
91 }
|
|
92
|
|
93 /* { dg-begin-multiline-output "" }
|
|
94 NN | free (ptr);
|
|
95 | ^~~~~~~~~~
|
|
96 'test_2': event 1
|
|
97 |
|
|
98 | NN | calls_free_2 (ptr);
|
|
99 | | ^~~~~~~~~~~~~~~~~~
|
|
100 | | |
|
|
101 | | (1) calling 'calls_free_2' from 'test_2'
|
|
102 |
|
|
103 +--> 'calls_free_2': event 2
|
|
104 |
|
|
105 | NN | free (ptr);
|
|
106 | | ^~~~~~~~~~
|
|
107 | | |
|
|
108 | | (2) first 'free' here
|
|
109 |
|
|
110 <------+
|
|
111 |
|
|
112 'test_2': events 3-4
|
|
113 |
|
|
114 | NN | calls_free_2 (ptr);
|
|
115 | | ^~~~~~~~~~~~~~~~~~
|
|
116 | | |
|
|
117 | | (3) returning to 'test_2' from 'calls_free_2'
|
|
118 |......
|
|
119 | NN | calls_free_2 (ptr);
|
|
120 | | ~~~~~~~~~~~~~~~~~~
|
|
121 | | |
|
|
122 | | (4) passing freed pointer 'ptr' in call to 'calls_free_2' from 'test_2'
|
|
123 |
|
|
124 +--> 'calls_free_2': event 5
|
|
125 |
|
|
126 | NN | free (ptr);
|
|
127 | | ^~~~~~~~~~
|
|
128 | | |
|
|
129 | | (5) second 'free' here; first 'free' was at (2)
|
|
130 |
|
|
131 { dg-end-multiline-output "" } */
|
|
132
|
|
133 // TODO: range cases
|
|
134
|
|
135 /* The call/return to this function shouldn't appear in the path. */
|
|
136
|
|
137 void called_by_test_3 (void)
|
|
138 {
|
|
139 }
|
|
140
|
|
141 void test_3 (void *ptr)
|
|
142 {
|
|
143 free (ptr);
|
|
144 called_by_test_3 ();
|
|
145 free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
|
|
146 }
|
|
147
|
|
148 /* { dg-begin-multiline-output "" }
|
|
149 NN | free (ptr);
|
|
150 | ^~~~~~~~~~
|
|
151 'test_3': events 1-2
|
|
152 |
|
|
153 | NN | free (ptr);
|
|
154 | | ^~~~~~~~~~
|
|
155 | | |
|
|
156 | | (1) first 'free' here
|
|
157 | NN | called_by_test_3 ();
|
|
158 | NN | free (ptr);
|
|
159 | | ~~~~~~~~~~
|
|
160 | | |
|
|
161 | | (2) second 'free' here; first 'free' was at (1)
|
|
162 |
|
|
163 { dg-end-multiline-output "" } */
|