1// SPDX-License-Identifier: GPL-2.0-only
2// Adds missing of_node_put() before return/break/goto statement within a for_each iterator for child nodes.
3//# False positives can be due to function calls within the for_each
4//# loop that may encapsulate an of_node_put.
5///
6// Confidence: High
7// Copyright: (C) 2020 Sumera Priyadarsini
8// URL: http://coccinelle.lip6.fr
9// Options: --no-includes --include-headers
10
11virtual patch
12virtual context
13virtual org
14virtual report
15
16@r@
17local idexpression n;
18expression e1,e2;
19iterator name for_each_node_by_name, for_each_node_by_type,
20for_each_compatible_node, for_each_matching_node,
21for_each_matching_node_and_match, for_each_child_of_node,
22for_each_available_child_of_node, for_each_node_with_property;
23iterator i;
24statement S;
25expression list [n1] es;
26@@
27
28(
29(
30for_each_node_by_name(n,e1) S
31|
32for_each_node_by_type(n,e1) S
33|
34for_each_compatible_node(n,e1,e2) S
35|
36for_each_matching_node(n,e1) S
37|
38for_each_matching_node_and_match(n,e1,e2) S
39|
40for_each_child_of_node(e1,n) S
41|
42for_each_available_child_of_node(e1,n) S
43|
44for_each_node_with_property(n,e1) S
45)
46&
47i(es,n,...) S
48)
49
50@ruleone depends on patch && !context && !org && !report@
51
52local idexpression r.n;
53iterator r.i,i1;
54expression e;
55expression list [r.n1] es;
56statement S;
57@@
58
59 i(es,n,...) {
60   ...
61(
62   of_node_put(n);
63|
64   e = n
65|
66   return n;
67|
68   i1(...,n,...) S
69|
70- return of_node_get(n);
71+ return n;
72|
73+  of_node_put(n);
74?  return ...;
75)
76   ... when any
77 }
78
79@ruletwo depends on patch && !context && !org && !report@
80
81local idexpression r.n;
82iterator r.i,i1,i2;
83expression e,e1;
84expression list [r.n1] es;
85statement S,S2;
86@@
87
88 i(es,n,...) {
89   ...
90(
91   of_node_put(n);
92|
93   e = n
94|
95   i1(...,n,...) S
96|
97+  of_node_put(n);
98?  break;
99)
100   ... when any
101 }
102... when != n
103    when strict
104    when forall
105(
106 n = e1;
107|
108?i2(...,n,...) S2
109)
110
111@rulethree depends on patch && !context && !org && !report exists@
112
113local idexpression r.n;
114iterator r.i,i1,i2;
115expression e,e1;
116identifier l;
117expression list [r.n1] es;
118statement S,S2;
119@@
120
121 i(es,n,...) {
122   ...
123(
124   of_node_put(n);
125|
126   e = n
127|
128   i1(...,n,...) S
129|
130+  of_node_put(n);
131?  goto l;
132)
133   ... when any
134 }
135... when exists
136l: ... when != n
137       when strict
138       when forall
139(
140 n = e1;
141|
142?i2(...,n,...) S2
143)
144
145// ----------------------------------------------------------------------------
146
147@ruleone_context depends on !patch && (context || org || report) exists@
148statement S;
149expression e;
150expression list[r.n1] es;
151iterator r.i, i1;
152local idexpression r.n;
153position j0, j1;
154@@
155
156 i@j0(es,n,...) {
157   ...
158(
159   of_node_put(n);
160|
161   e = n
162|
163   return n;
164|
165   i1(...,n,...) S
166|
167  return @j1 ...;
168)
169   ... when any
170 }
171
172@ruleone_disj depends on !patch && (context || org || report)@
173expression list[r.n1] es;
174iterator r.i;
175local idexpression r.n;
176position ruleone_context.j0, ruleone_context.j1;
177@@
178
179*  i@j0(es,n,...) {
180   ...
181*return  @j1...;
182   ... when any
183 }
184
185@ruletwo_context depends on !patch && (context || org || report) exists@
186statement S, S2;
187expression e, e1;
188expression list[r.n1] es;
189iterator r.i, i1, i2;
190local idexpression r.n;
191position j0, j2;
192@@
193
194 i@j0(es,n,...) {
195   ...
196(
197   of_node_put(n);
198|
199   e = n
200|
201   i1(...,n,...) S
202|
203  break@j2;
204)
205   ... when any
206 }
207... when != n
208    when strict
209    when forall
210(
211 n = e1;
212|
213?i2(...,n,...) S2
214)
215
216@ruletwo_disj depends on !patch && (context || org || report)@
217statement S2;
218expression e1;
219expression list[r.n1] es;
220iterator r.i, i2;
221local idexpression r.n;
222position ruletwo_context.j0, ruletwo_context.j2;
223@@
224
225*  i@j0(es,n,...) {
226   ...
227*break @j2;
228   ... when any
229 }
230... when != n
231    when strict
232    when forall
233(
234  n = e1;
235|
236?i2(...,n,...) S2
237)
238
239@rulethree_context depends on !patch && (context || org || report) exists@
240identifier l;
241statement S,S2;
242expression e, e1;
243expression list[r.n1] es;
244iterator r.i, i1, i2;
245local idexpression r.n;
246position j0, j3;
247@@
248
249 i@j0(es,n,...) {
250   ...
251(
252   of_node_put(n);
253|
254   e = n
255|
256   i1(...,n,...) S
257|
258  goto l@j3;
259)
260  ... when any
261 }
262... when exists
263l:
264... when != n
265    when strict
266    when forall
267(
268 n = e1;
269|
270?i2(...,n,...) S2
271)
272
273@rulethree_disj depends on !patch && (context || org || report) exists@
274identifier l;
275statement S2;
276expression e1;
277expression list[r.n1] es;
278iterator r.i, i2;
279local idexpression r.n;
280position rulethree_context.j0, rulethree_context.j3;
281@@
282
283*  i@j0(es,n,...) {
284   ...
285*goto l@j3;
286   ... when any
287 }
288... when exists
289 l:
290 ... when != n
291     when strict
292     when forall
293(
294 n = e1;
295|
296?i2(...,n,...) S2
297)
298
299// ----------------------------------------------------------------------------
300
301@script:python ruleone_org depends on org@
302i << r.i;
303j0 << ruleone_context.j0;
304j1 << ruleone_context. j1;
305@@
306
307msg = "WARNING: Function \"%s\" should have of_node_put() before return " % (i)
308coccilib.org.print_safe_todo(j0[0], msg)
309coccilib.org.print_link(j1[0], "")
310
311@script:python ruletwo_org depends on org@
312i << r.i;
313j0 << ruletwo_context.j0;
314j2 << ruletwo_context.j2;
315@@
316
317msg = "WARNING: Function \"%s\" should have of_node_put() before break " % (i)
318coccilib.org.print_safe_todo(j0[0], msg)
319coccilib.org.print_link(j2[0], "")
320
321@script:python rulethree_org depends on org@
322i << r.i;
323j0 << rulethree_context.j0;
324j3 << rulethree_context.j3;
325@@
326
327msg = "WARNING: Function \"%s\" should have of_node_put() before goto " % (i)
328coccilib.org.print_safe_todo(j0[0], msg)
329coccilib.org.print_link(j3[0], "")
330
331// ----------------------------------------------------------------------------
332
333@script:python ruleone_report depends on report@
334i << r.i;
335j0 << ruleone_context.j0;
336j1 << ruleone_context.j1;
337@@
338
339msg = "WARNING: Function \"%s\" should have of_node_put() before return around line %s." % (i, j1[0].line)
340coccilib.report.print_report(j0[0], msg)
341
342@script:python ruletwo_report depends on report@
343i << r.i;
344j0 << ruletwo_context.j0;
345j2 << ruletwo_context.j2;
346@@
347
348msg = "WARNING: Function \"%s\" should have of_node_put() before break around line %s." % (i,j2[0].line)
349coccilib.report.print_report(j0[0], msg)
350
351@script:python rulethree_report depends on report@
352i << r.i;
353j0 << rulethree_context.j0;
354j3 << rulethree_context.j3;
355@@
356
357msg = "WARNING: Function \"%s\" should have of_node_put() before goto around lines %s." % (i,j3[0].line)
358coccilib.report.print_report(j0[0], msg)
359