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