Commit 82c4340b0a3ccf090ef38fa111363018cf0594c8
Committed by
Michal Marek
1 parent
f853f8305b
Exists in
master
and in
4 other branches
Add scripts/coccinelle/deref_null.cocci
Add a Coccinelle file to identify the dereferences of NULL variables This semantic patch identifies when a variable is known to be NULL after a test, but it is still dereferenced later. Signed-off-by: Nicolas Palix <npalix@diku.dk> Signed-off-by: Julia Lawall <julia@diku.dk> Signed-off-by: Michal Marek <mmarek@suse.cz>
Showing 1 changed file with 293 additions and 0 deletions Side-by-side Diff
scripts/coccinelle/deref_null.cocci
1 | +/// | |
2 | +/// A variable is dereference under a NULL test. | |
3 | +/// Even though it is know to be NULL. | |
4 | +/// | |
5 | +// Confidence: Moderate | |
6 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
7 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
8 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
9 | +// URL: http://coccinelle.lip6.fr/ | |
10 | +// Comments: -I ... -all_includes can give more complete results | |
11 | +// Options: | |
12 | + | |
13 | +virtual context | |
14 | +virtual patch | |
15 | +virtual org | |
16 | +virtual report | |
17 | + | |
18 | +@initialize:python depends on !context && patch && !org && !report@ | |
19 | + | |
20 | +import sys | |
21 | +print >> sys.stderr, "This semantic patch does not support the 'patch' mode." | |
22 | + | |
23 | +@depends on patch@ | |
24 | +@@ | |
25 | + | |
26 | +this_rule_should_never_matches(); | |
27 | + | |
28 | +@ifm depends on !patch@ | |
29 | +expression *E; | |
30 | +statement S1,S2; | |
31 | +position p1; | |
32 | +@@ | |
33 | + | |
34 | +if@p1 ((E == NULL && ...) || ...) S1 else S2 | |
35 | + | |
36 | +// The following two rules are separate, because both can match a single | |
37 | +// expression in different ways | |
38 | +@pr1 depends on !patch expression@ | |
39 | +expression *ifm.E; | |
40 | +identifier f; | |
41 | +position p1; | |
42 | +@@ | |
43 | + | |
44 | + (E != NULL && ...) ? <+...E->f@p1...+> : ... | |
45 | + | |
46 | +@pr2 depends on !patch expression@ | |
47 | +expression *ifm.E; | |
48 | +identifier f; | |
49 | +position p2; | |
50 | +@@ | |
51 | + | |
52 | +( | |
53 | + (E != NULL) && ... && <+...E->f@p2...+> | |
54 | +| | |
55 | + (E == NULL) || ... || <+...E->f@p2...+> | |
56 | +| | |
57 | + sizeof(<+...E->f@p2...+>) | |
58 | +) | |
59 | + | |
60 | +// For org and report modes | |
61 | + | |
62 | +@r depends on !context && !patch && (org || report) exists@ | |
63 | +expression subE <= ifm.E; | |
64 | +expression *ifm.E; | |
65 | +expression E1,E2; | |
66 | +identifier f; | |
67 | +statement S1,S2,S3,S4; | |
68 | +iterator iter; | |
69 | +position p!={pr1.p1,pr2.p2}; | |
70 | +position ifm.p1; | |
71 | +@@ | |
72 | + | |
73 | +if@p1 ((E == NULL && ...) || ...) | |
74 | +{ | |
75 | + ... when != if (...) S1 else S2 | |
76 | +( | |
77 | + iter(subE,...) S4 // no use | |
78 | +| | |
79 | + list_remove_head(E2,subE,...) | |
80 | +| | |
81 | + subE = E1 | |
82 | +| | |
83 | + for(subE = E1;...;...) S4 | |
84 | +| | |
85 | + subE++ | |
86 | +| | |
87 | + ++subE | |
88 | +| | |
89 | + --subE | |
90 | +| | |
91 | + subE-- | |
92 | +| | |
93 | + &subE | |
94 | +| | |
95 | + E->f@p // bad use | |
96 | +) | |
97 | + ... when any | |
98 | + return ...; | |
99 | +} | |
100 | +else S3 | |
101 | + | |
102 | +@script:python depends on !context && !patch && !org && report@ | |
103 | +p << r.p; | |
104 | +p1 << ifm.p1; | |
105 | +x << ifm.E; | |
106 | +@@ | |
107 | + | |
108 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
109 | +coccilib.report.print_report(p[0], msg) | |
110 | +cocci.include_match(False) | |
111 | + | |
112 | +@script:python depends on !context && !patch && org && !report@ | |
113 | +p << r.p; | |
114 | +p1 << ifm.p1; | |
115 | +x << ifm.E; | |
116 | +@@ | |
117 | + | |
118 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
119 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
120 | +cocci.print_main(msg_safe,p) | |
121 | +cocci.include_match(False) | |
122 | + | |
123 | +@s depends on !context && !patch && (org || report) exists@ | |
124 | +expression subE <= ifm.E; | |
125 | +expression *ifm.E; | |
126 | +expression E1,E2; | |
127 | +identifier f; | |
128 | +statement S1,S2,S3,S4; | |
129 | +iterator iter; | |
130 | +position p!={pr1.p1,pr2.p2}; | |
131 | +position ifm.p1; | |
132 | +@@ | |
133 | + | |
134 | +if@p1 ((E == NULL && ...) || ...) | |
135 | +{ | |
136 | + ... when != if (...) S1 else S2 | |
137 | +( | |
138 | + iter(subE,...) S4 // no use | |
139 | +| | |
140 | + list_remove_head(E2,subE,...) | |
141 | +| | |
142 | + subE = E1 | |
143 | +| | |
144 | + for(subE = E1;...;...) S4 | |
145 | +| | |
146 | + subE++ | |
147 | +| | |
148 | + ++subE | |
149 | +| | |
150 | + --subE | |
151 | +| | |
152 | + subE-- | |
153 | +| | |
154 | + &subE | |
155 | +| | |
156 | + E->f@p // bad use | |
157 | +) | |
158 | + ... when any | |
159 | +} | |
160 | +else S3 | |
161 | + | |
162 | +@script:python depends on !context && !patch && !org && report@ | |
163 | +p << s.p; | |
164 | +p1 << ifm.p1; | |
165 | +x << ifm.E; | |
166 | +@@ | |
167 | + | |
168 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
169 | +coccilib.report.print_report(p[0], msg) | |
170 | + | |
171 | +@script:python depends on !context && !patch && org && !report@ | |
172 | +p << s.p; | |
173 | +p1 << ifm.p1; | |
174 | +x << ifm.E; | |
175 | +@@ | |
176 | + | |
177 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
178 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
179 | +cocci.print_main(msg_safe,p) | |
180 | + | |
181 | +// For context mode | |
182 | + | |
183 | +@depends on context && !patch && !org && !report exists@ | |
184 | +expression subE <= ifm.E; | |
185 | +expression *ifm.E; | |
186 | +expression E1,E2; | |
187 | +identifier f; | |
188 | +statement S1,S2,S3,S4; | |
189 | +iterator iter; | |
190 | +position p!={pr1.p1,pr2.p2}; | |
191 | +position ifm.p1; | |
192 | +@@ | |
193 | + | |
194 | +if@p1 ((E == NULL && ...) || ...) | |
195 | +{ | |
196 | + ... when != if (...) S1 else S2 | |
197 | +( | |
198 | + iter(subE,...) S4 // no use | |
199 | +| | |
200 | + list_remove_head(E2,subE,...) | |
201 | +| | |
202 | + subE = E1 | |
203 | +| | |
204 | + for(subE = E1;...;...) S4 | |
205 | +| | |
206 | + subE++ | |
207 | +| | |
208 | + ++subE | |
209 | +| | |
210 | + --subE | |
211 | +| | |
212 | + subE-- | |
213 | +| | |
214 | + &subE | |
215 | +| | |
216 | +* E->f@p // bad use | |
217 | +) | |
218 | + ... when any | |
219 | + return ...; | |
220 | +} | |
221 | +else S3 | |
222 | + | |
223 | +// The following three rules are duplicates of ifm, pr1 and pr2 respectively. | |
224 | +// It is need because the previous rule as already made a "change". | |
225 | + | |
226 | +@ifm1 depends on !patch@ | |
227 | +expression *E; | |
228 | +statement S1,S2; | |
229 | +position p1; | |
230 | +@@ | |
231 | + | |
232 | +if@p1 ((E == NULL && ...) || ...) S1 else S2 | |
233 | + | |
234 | +@pr11 depends on !patch expression@ | |
235 | +expression *ifm1.E; | |
236 | +identifier f; | |
237 | +position p1; | |
238 | +@@ | |
239 | + | |
240 | + (E != NULL && ...) ? <+...E->f@p1...+> : ... | |
241 | + | |
242 | +@pr12 depends on !patch expression@ | |
243 | +expression *ifm1.E; | |
244 | +identifier f; | |
245 | +position p2; | |
246 | +@@ | |
247 | + | |
248 | +( | |
249 | + (E != NULL) && ... && <+...E->f@p2...+> | |
250 | +| | |
251 | + (E == NULL) || ... || <+...E->f@p2...+> | |
252 | +| | |
253 | + sizeof(<+...E->f@p2...+>) | |
254 | +) | |
255 | + | |
256 | +@depends on context && !patch && !org && !report exists@ | |
257 | +expression subE <= ifm1.E; | |
258 | +expression *ifm1.E; | |
259 | +expression E1,E2; | |
260 | +identifier f; | |
261 | +statement S1,S2,S3,S4; | |
262 | +iterator iter; | |
263 | +position p!={pr11.p1,pr12.p2}; | |
264 | +position ifm1.p1; | |
265 | +@@ | |
266 | + | |
267 | +if@p1 ((E == NULL && ...) || ...) | |
268 | +{ | |
269 | + ... when != if (...) S1 else S2 | |
270 | +( | |
271 | + iter(subE,...) S4 // no use | |
272 | +| | |
273 | + list_remove_head(E2,subE,...) | |
274 | +| | |
275 | + subE = E1 | |
276 | +| | |
277 | + for(subE = E1;...;...) S4 | |
278 | +| | |
279 | + subE++ | |
280 | +| | |
281 | + ++subE | |
282 | +| | |
283 | + --subE | |
284 | +| | |
285 | + subE-- | |
286 | +| | |
287 | + &subE | |
288 | +| | |
289 | +* E->f@p // bad use | |
290 | +) | |
291 | + ... when any | |
292 | +} | |
293 | +else S3 |