0001 // SPDX-License-Identifier: GPL-2.0-only
0002 // Adds missing of_node_put() before return/break/goto statement within a for_each iterator for child nodes.
0003 //# False positives can be due to function calls within the for_each
0004 //# loop that may encapsulate an of_node_put.
0005 ///
0006 // Confidence: High
0007 // Copyright: (C) 2020 Sumera Priyadarsini
0008 // URL: https://coccinelle.gitlabpages.inria.fr/website
0009 // Options: --no-includes --include-headers
0010
0011 virtual patch
0012 virtual context
0013 virtual org
0014 virtual report
0015
0016 @r@
0017 local idexpression n;
0018 expression e1,e2;
0019 iterator name for_each_node_by_name, for_each_node_by_type,
0020 for_each_compatible_node, for_each_matching_node,
0021 for_each_matching_node_and_match, for_each_child_of_node,
0022 for_each_available_child_of_node, for_each_node_with_property;
0023 iterator i;
0024 statement S;
0025 expression list [n1] es;
0026 @@
0027
0028 (
0029 (
0030 for_each_node_by_name(n,e1) S
0031 |
0032 for_each_node_by_type(n,e1) S
0033 |
0034 for_each_compatible_node(n,e1,e2) S
0035 |
0036 for_each_matching_node(n,e1) S
0037 |
0038 for_each_matching_node_and_match(n,e1,e2) S
0039 |
0040 for_each_child_of_node(e1,n) S
0041 |
0042 for_each_available_child_of_node(e1,n) S
0043 |
0044 for_each_node_with_property(n,e1) S
0045 )
0046 &
0047 i(es,n,...) S
0048 )
0049
0050 @ruleone depends on patch && !context && !org && !report@
0051
0052 local idexpression r.n;
0053 iterator r.i,i1;
0054 expression e;
0055 expression list [r.n1] es;
0056 statement S;
0057 @@
0058
0059 i(es,n,...) {
0060 ...
0061 (
0062 of_node_put(n);
0063 |
0064 e = n
0065 |
0066 return n;
0067 |
0068 i1(...,n,...) S
0069 |
0070 - return of_node_get(n);
0071 + return n;
0072 |
0073 + of_node_put(n);
0074 ? return ...;
0075 )
0076 ... when any
0077 }
0078
0079 @ruletwo depends on patch && !context && !org && !report@
0080
0081 local idexpression r.n;
0082 iterator r.i,i1,i2;
0083 expression e,e1;
0084 expression list [r.n1] es;
0085 statement S,S2;
0086 @@
0087
0088 i(es,n,...) {
0089 ...
0090 (
0091 of_node_put(n);
0092 |
0093 e = n
0094 |
0095 i1(...,n,...) S
0096 |
0097 + of_node_put(n);
0098 ? break;
0099 )
0100 ... when any
0101 }
0102 ... when != n
0103 when strict
0104 when forall
0105 (
0106 n = e1;
0107 |
0108 ?i2(...,n,...) S2
0109 )
0110
0111 @rulethree depends on patch && !context && !org && !report exists@
0112
0113 local idexpression r.n;
0114 iterator r.i,i1,i2;
0115 expression e,e1;
0116 identifier l;
0117 expression list [r.n1] es;
0118 statement S,S2;
0119 @@
0120
0121 i(es,n,...) {
0122 ...
0123 (
0124 of_node_put(n);
0125 |
0126 e = n
0127 |
0128 i1(...,n,...) S
0129 |
0130 + of_node_put(n);
0131 ? goto l;
0132 )
0133 ... when any
0134 }
0135 ... when exists
0136 l: ... when != n
0137 when strict
0138 when forall
0139 (
0140 n = e1;
0141 |
0142 ?i2(...,n,...) S2
0143 )
0144
0145 // ----------------------------------------------------------------------------
0146
0147 @ruleone_context depends on !patch && (context || org || report) exists@
0148 statement S;
0149 expression e;
0150 expression list[r.n1] es;
0151 iterator r.i, i1;
0152 local idexpression r.n;
0153 position j0, j1;
0154 @@
0155
0156 i@j0(es,n,...) {
0157 ...
0158 (
0159 of_node_put(n);
0160 |
0161 e = n
0162 |
0163 return n;
0164 |
0165 i1(...,n,...) S
0166 |
0167 return @j1 ...;
0168 )
0169 ... when any
0170 }
0171
0172 @ruleone_disj depends on !patch && (context || org || report)@
0173 expression list[r.n1] es;
0174 iterator r.i;
0175 local idexpression r.n;
0176 position ruleone_context.j0, ruleone_context.j1;
0177 @@
0178
0179 * i@j0(es,n,...) {
0180 ...
0181 *return @j1...;
0182 ... when any
0183 }
0184
0185 @ruletwo_context depends on !patch && (context || org || report) exists@
0186 statement S, S2;
0187 expression e, e1;
0188 expression list[r.n1] es;
0189 iterator r.i, i1, i2;
0190 local idexpression r.n;
0191 position j0, j2;
0192 @@
0193
0194 i@j0(es,n,...) {
0195 ...
0196 (
0197 of_node_put(n);
0198 |
0199 e = n
0200 |
0201 i1(...,n,...) S
0202 |
0203 break@j2;
0204 )
0205 ... when any
0206 }
0207 ... when != n
0208 when strict
0209 when forall
0210 (
0211 n = e1;
0212 |
0213 ?i2(...,n,...) S2
0214 )
0215
0216 @ruletwo_disj depends on !patch && (context || org || report)@
0217 statement S2;
0218 expression e1;
0219 expression list[r.n1] es;
0220 iterator r.i, i2;
0221 local idexpression r.n;
0222 position ruletwo_context.j0, ruletwo_context.j2;
0223 @@
0224
0225 * i@j0(es,n,...) {
0226 ...
0227 *break @j2;
0228 ... when any
0229 }
0230 ... when != n
0231 when strict
0232 when forall
0233 (
0234 n = e1;
0235 |
0236 ?i2(...,n,...) S2
0237 )
0238
0239 @rulethree_context depends on !patch && (context || org || report) exists@
0240 identifier l;
0241 statement S,S2;
0242 expression e, e1;
0243 expression list[r.n1] es;
0244 iterator r.i, i1, i2;
0245 local idexpression r.n;
0246 position j0, j3;
0247 @@
0248
0249 i@j0(es,n,...) {
0250 ...
0251 (
0252 of_node_put(n);
0253 |
0254 e = n
0255 |
0256 i1(...,n,...) S
0257 |
0258 goto l@j3;
0259 )
0260 ... when any
0261 }
0262 ... when exists
0263 l:
0264 ... when != n
0265 when strict
0266 when forall
0267 (
0268 n = e1;
0269 |
0270 ?i2(...,n,...) S2
0271 )
0272
0273 @rulethree_disj depends on !patch && (context || org || report) exists@
0274 identifier l;
0275 statement S2;
0276 expression e1;
0277 expression list[r.n1] es;
0278 iterator r.i, i2;
0279 local idexpression r.n;
0280 position rulethree_context.j0, rulethree_context.j3;
0281 @@
0282
0283 * i@j0(es,n,...) {
0284 ...
0285 *goto l@j3;
0286 ... when any
0287 }
0288 ... when exists
0289 l:
0290 ... when != n
0291 when strict
0292 when forall
0293 (
0294 n = e1;
0295 |
0296 ?i2(...,n,...) S2
0297 )
0298
0299 // ----------------------------------------------------------------------------
0300
0301 @script:python ruleone_org depends on org@
0302 i << r.i;
0303 j0 << ruleone_context.j0;
0304 j1 << ruleone_context. j1;
0305 @@
0306
0307 msg = "WARNING: Function \"%s\" should have of_node_put() before return " % (i)
0308 coccilib.org.print_safe_todo(j0[0], msg)
0309 coccilib.org.print_link(j1[0], "")
0310
0311 @script:python ruletwo_org depends on org@
0312 i << r.i;
0313 j0 << ruletwo_context.j0;
0314 j2 << ruletwo_context.j2;
0315 @@
0316
0317 msg = "WARNING: Function \"%s\" should have of_node_put() before break " % (i)
0318 coccilib.org.print_safe_todo(j0[0], msg)
0319 coccilib.org.print_link(j2[0], "")
0320
0321 @script:python rulethree_org depends on org@
0322 i << r.i;
0323 j0 << rulethree_context.j0;
0324 j3 << rulethree_context.j3;
0325 @@
0326
0327 msg = "WARNING: Function \"%s\" should have of_node_put() before goto " % (i)
0328 coccilib.org.print_safe_todo(j0[0], msg)
0329 coccilib.org.print_link(j3[0], "")
0330
0331 // ----------------------------------------------------------------------------
0332
0333 @script:python ruleone_report depends on report@
0334 i << r.i;
0335 j0 << ruleone_context.j0;
0336 j1 << ruleone_context.j1;
0337 @@
0338
0339 msg = "WARNING: Function \"%s\" should have of_node_put() before return around line %s." % (i, j1[0].line)
0340 coccilib.report.print_report(j0[0], msg)
0341
0342 @script:python ruletwo_report depends on report@
0343 i << r.i;
0344 j0 << ruletwo_context.j0;
0345 j2 << ruletwo_context.j2;
0346 @@
0347
0348 msg = "WARNING: Function \"%s\" should have of_node_put() before break around line %s." % (i,j2[0].line)
0349 coccilib.report.print_report(j0[0], msg)
0350
0351 @script:python rulethree_report depends on report@
0352 i << r.i;
0353 j0 << rulethree_context.j0;
0354 j3 << rulethree_context.j3;
0355 @@
0356
0357 msg = "WARNING: Function \"%s\" should have of_node_put() before goto around lines %s." % (i,j3[0].line)
0358 coccilib.report.print_report(j0[0], msg)