xref: /OK3568_Linux_fs/kernel/scripts/coccinelle/iterators/itnull.cocci (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun// SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun/// Many iterators have the property that the first argument is always bound
3*4882a593Smuzhiyun/// to a real list element, never NULL.
4*4882a593Smuzhiyun//# False positives arise for some iterators that do not have this property,
5*4882a593Smuzhiyun//# or in cases when the loop cursor is reassigned.  The latter should only
6*4882a593Smuzhiyun//# happen when the matched code is on the way to a loop exit (break, goto,
7*4882a593Smuzhiyun//# or return).
8*4882a593Smuzhiyun///
9*4882a593Smuzhiyun// Confidence: Moderate
10*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Nicolas Palix.
11*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
12*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
13*4882a593Smuzhiyun// URL: http://coccinelle.lip6.fr/
14*4882a593Smuzhiyun// Comments:
15*4882a593Smuzhiyun// Options: --no-includes --include-headers
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunvirtual patch
18*4882a593Smuzhiyunvirtual context
19*4882a593Smuzhiyunvirtual org
20*4882a593Smuzhiyunvirtual report
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun@depends on patch@
23*4882a593Smuzhiyuniterator I;
24*4882a593Smuzhiyunexpression x,E,E1,E2;
25*4882a593Smuzhiyunstatement S,S1,S2;
26*4882a593Smuzhiyun@@
27*4882a593Smuzhiyun
28*4882a593SmuzhiyunI(x,...) { <...
29*4882a593Smuzhiyun(
30*4882a593Smuzhiyun- if (x == NULL && ...) S
31*4882a593Smuzhiyun|
32*4882a593Smuzhiyun- if (x != NULL || ...)
33*4882a593Smuzhiyun  S
34*4882a593Smuzhiyun|
35*4882a593Smuzhiyun- (x == NULL) ||
36*4882a593Smuzhiyun  E
37*4882a593Smuzhiyun|
38*4882a593Smuzhiyun- (x != NULL) &&
39*4882a593Smuzhiyun  E
40*4882a593Smuzhiyun|
41*4882a593Smuzhiyun- (x == NULL && ...) ? E1 :
42*4882a593Smuzhiyun  E2
43*4882a593Smuzhiyun|
44*4882a593Smuzhiyun- (x != NULL || ...) ?
45*4882a593Smuzhiyun  E1
46*4882a593Smuzhiyun- : E2
47*4882a593Smuzhiyun|
48*4882a593Smuzhiyun- if (x == NULL && ...) S1 else
49*4882a593Smuzhiyun  S2
50*4882a593Smuzhiyun|
51*4882a593Smuzhiyun- if (x != NULL || ...)
52*4882a593Smuzhiyun  S1
53*4882a593Smuzhiyun- else S2
54*4882a593Smuzhiyun|
55*4882a593Smuzhiyun+ BAD(
56*4882a593Smuzhiyun  x == NULL
57*4882a593Smuzhiyun+ )
58*4882a593Smuzhiyun|
59*4882a593Smuzhiyun+ BAD(
60*4882a593Smuzhiyun  x != NULL
61*4882a593Smuzhiyun+ )
62*4882a593Smuzhiyun)
63*4882a593Smuzhiyun  ...> }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun@r depends on !patch exists@
66*4882a593Smuzhiyuniterator I;
67*4882a593Smuzhiyunexpression x,E;
68*4882a593Smuzhiyunposition p1,p2;
69*4882a593Smuzhiyun@@
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun*I@p1(x,...)
72*4882a593Smuzhiyun{ ... when != x = E
73*4882a593Smuzhiyun(
74*4882a593Smuzhiyun*  x@p2 == NULL
75*4882a593Smuzhiyun|
76*4882a593Smuzhiyun*  x@p2 != NULL
77*4882a593Smuzhiyun)
78*4882a593Smuzhiyun  ... when any
79*4882a593Smuzhiyun}
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun@script:python depends on org@
82*4882a593Smuzhiyunp1 << r.p1;
83*4882a593Smuzhiyunp2 << r.p2;
84*4882a593Smuzhiyun@@
85*4882a593Smuzhiyun
86*4882a593Smuzhiyuncocci.print_main("iterator-bound variable",p1)
87*4882a593Smuzhiyuncocci.print_secs("useless NULL test",p2)
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun@script:python depends on report@
90*4882a593Smuzhiyunp1 << r.p1;
91*4882a593Smuzhiyunp2 << r.p2;
92*4882a593Smuzhiyun@@
93*4882a593Smuzhiyun
94*4882a593Smuzhiyunmsg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
95*4882a593Smuzhiyuncoccilib.report.print_report(p2[0], msg)
96