xref: /linux/scripts/coccinelle/iterators/itnull.cocci (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
17f904d7eSThomas Gleixner// SPDX-License-Identifier: GPL-2.0-only
2afc48a82SNicolas Palix/// Many iterators have the property that the first argument is always bound
329a36d4dSJulia Lawall/// to a real list element, never NULL.
429a36d4dSJulia Lawall//# False positives arise for some iterators that do not have this property,
529a36d4dSJulia Lawall//# or in cases when the loop cursor is reassigned.  The latter should only
629a36d4dSJulia Lawall//# happen when the matched code is on the way to a loop exit (break, goto,
729a36d4dSJulia Lawall//# or return).
8afc48a82SNicolas Palix///
9afc48a82SNicolas Palix// Confidence: Moderate
107f904d7eSThomas Gleixner// Copyright: (C) 2010-2012 Nicolas Palix.
117f904d7eSThomas Gleixner// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
127f904d7eSThomas Gleixner// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
13*f01701ceSJulia Lawall// URL: https://coccinelle.gitlabpages.inria.fr/website
14afc48a82SNicolas Palix// Comments:
1593f14468SNicolas Palix// Options: --no-includes --include-headers
16afc48a82SNicolas Palix
17afc48a82SNicolas Palixvirtual patch
1829a36d4dSJulia Lawallvirtual context
1929a36d4dSJulia Lawallvirtual org
2029a36d4dSJulia Lawallvirtual report
21afc48a82SNicolas Palix
2229a36d4dSJulia Lawall@depends on patch@
23afc48a82SNicolas Palixiterator I;
24afc48a82SNicolas Palixexpression x,E,E1,E2;
25afc48a82SNicolas Palixstatement S,S1,S2;
26afc48a82SNicolas Palix@@
27afc48a82SNicolas Palix
28afc48a82SNicolas PalixI(x,...) { <...
29afc48a82SNicolas Palix(
30afc48a82SNicolas Palix- if (x == NULL && ...) S
31afc48a82SNicolas Palix|
32afc48a82SNicolas Palix- if (x != NULL || ...)
33afc48a82SNicolas Palix  S
34afc48a82SNicolas Palix|
35afc48a82SNicolas Palix- (x == NULL) ||
36afc48a82SNicolas Palix  E
37afc48a82SNicolas Palix|
38afc48a82SNicolas Palix- (x != NULL) &&
39afc48a82SNicolas Palix  E
40afc48a82SNicolas Palix|
41afc48a82SNicolas Palix- (x == NULL && ...) ? E1 :
42afc48a82SNicolas Palix  E2
43afc48a82SNicolas Palix|
44afc48a82SNicolas Palix- (x != NULL || ...) ?
45afc48a82SNicolas Palix  E1
46afc48a82SNicolas Palix- : E2
47afc48a82SNicolas Palix|
48afc48a82SNicolas Palix- if (x == NULL && ...) S1 else
49afc48a82SNicolas Palix  S2
50afc48a82SNicolas Palix|
51afc48a82SNicolas Palix- if (x != NULL || ...)
52afc48a82SNicolas Palix  S1
53afc48a82SNicolas Palix- else S2
54afc48a82SNicolas Palix|
55afc48a82SNicolas Palix+ BAD(
56afc48a82SNicolas Palix  x == NULL
57afc48a82SNicolas Palix+ )
58afc48a82SNicolas Palix|
59afc48a82SNicolas Palix+ BAD(
60afc48a82SNicolas Palix  x != NULL
61afc48a82SNicolas Palix+ )
62afc48a82SNicolas Palix)
63afc48a82SNicolas Palix  ...> }
6429a36d4dSJulia Lawall
6529a36d4dSJulia Lawall@r depends on !patch exists@
6629a36d4dSJulia Lawalliterator I;
6729a36d4dSJulia Lawallexpression x,E;
6829a36d4dSJulia Lawallposition p1,p2;
6929a36d4dSJulia Lawall@@
7029a36d4dSJulia Lawall
7129a36d4dSJulia Lawall*I@p1(x,...)
7229a36d4dSJulia Lawall{ ... when != x = E
7329a36d4dSJulia Lawall(
7429a36d4dSJulia Lawall*  x@p2 == NULL
7529a36d4dSJulia Lawall|
7629a36d4dSJulia Lawall*  x@p2 != NULL
7729a36d4dSJulia Lawall)
7829a36d4dSJulia Lawall  ... when any
7929a36d4dSJulia Lawall}
8029a36d4dSJulia Lawall
8129a36d4dSJulia Lawall@script:python depends on org@
8229a36d4dSJulia Lawallp1 << r.p1;
8329a36d4dSJulia Lawallp2 << r.p2;
8429a36d4dSJulia Lawall@@
8529a36d4dSJulia Lawall
8629a36d4dSJulia Lawallcocci.print_main("iterator-bound variable",p1)
8729a36d4dSJulia Lawallcocci.print_secs("useless NULL test",p2)
8829a36d4dSJulia Lawall
8929a36d4dSJulia Lawall@script:python depends on report@
9029a36d4dSJulia Lawallp1 << r.p1;
9129a36d4dSJulia Lawallp2 << r.p2;
9229a36d4dSJulia Lawall@@
9329a36d4dSJulia Lawall
9429a36d4dSJulia Lawallmsg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
9529a36d4dSJulia Lawallcoccilib.report.print_report(p2[0], msg)
96