18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/// Many iterators have the property that the first argument is always bound
38c2ecf20Sopenharmony_ci/// to a real list element, never NULL.
48c2ecf20Sopenharmony_ci//# False positives arise for some iterators that do not have this property,
58c2ecf20Sopenharmony_ci//# or in cases when the loop cursor is reassigned.  The latter should only
68c2ecf20Sopenharmony_ci//# happen when the matched code is on the way to a loop exit (break, goto,
78c2ecf20Sopenharmony_ci//# or return).
88c2ecf20Sopenharmony_ci///
98c2ecf20Sopenharmony_ci// Confidence: Moderate
108c2ecf20Sopenharmony_ci// Copyright: (C) 2010-2012 Nicolas Palix.
118c2ecf20Sopenharmony_ci// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
128c2ecf20Sopenharmony_ci// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
138c2ecf20Sopenharmony_ci// URL: http://coccinelle.lip6.fr/
148c2ecf20Sopenharmony_ci// Comments:
158c2ecf20Sopenharmony_ci// Options: --no-includes --include-headers
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_civirtual patch
188c2ecf20Sopenharmony_civirtual context
198c2ecf20Sopenharmony_civirtual org
208c2ecf20Sopenharmony_civirtual report
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci@depends on patch@
238c2ecf20Sopenharmony_ciiterator I;
248c2ecf20Sopenharmony_ciexpression x,E,E1,E2;
258c2ecf20Sopenharmony_cistatement S,S1,S2;
268c2ecf20Sopenharmony_ci@@
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ciI(x,...) { <...
298c2ecf20Sopenharmony_ci(
308c2ecf20Sopenharmony_ci- if (x == NULL && ...) S
318c2ecf20Sopenharmony_ci|
328c2ecf20Sopenharmony_ci- if (x != NULL || ...)
338c2ecf20Sopenharmony_ci  S
348c2ecf20Sopenharmony_ci|
358c2ecf20Sopenharmony_ci- (x == NULL) ||
368c2ecf20Sopenharmony_ci  E
378c2ecf20Sopenharmony_ci|
388c2ecf20Sopenharmony_ci- (x != NULL) &&
398c2ecf20Sopenharmony_ci  E
408c2ecf20Sopenharmony_ci|
418c2ecf20Sopenharmony_ci- (x == NULL && ...) ? E1 :
428c2ecf20Sopenharmony_ci  E2
438c2ecf20Sopenharmony_ci|
448c2ecf20Sopenharmony_ci- (x != NULL || ...) ?
458c2ecf20Sopenharmony_ci  E1
468c2ecf20Sopenharmony_ci- : E2
478c2ecf20Sopenharmony_ci|
488c2ecf20Sopenharmony_ci- if (x == NULL && ...) S1 else
498c2ecf20Sopenharmony_ci  S2
508c2ecf20Sopenharmony_ci|
518c2ecf20Sopenharmony_ci- if (x != NULL || ...)
528c2ecf20Sopenharmony_ci  S1
538c2ecf20Sopenharmony_ci- else S2
548c2ecf20Sopenharmony_ci|
558c2ecf20Sopenharmony_ci+ BAD(
568c2ecf20Sopenharmony_ci  x == NULL
578c2ecf20Sopenharmony_ci+ )
588c2ecf20Sopenharmony_ci|
598c2ecf20Sopenharmony_ci+ BAD(
608c2ecf20Sopenharmony_ci  x != NULL
618c2ecf20Sopenharmony_ci+ )
628c2ecf20Sopenharmony_ci)
638c2ecf20Sopenharmony_ci  ...> }
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci@r depends on !patch exists@
668c2ecf20Sopenharmony_ciiterator I;
678c2ecf20Sopenharmony_ciexpression x,E;
688c2ecf20Sopenharmony_ciposition p1,p2;
698c2ecf20Sopenharmony_ci@@
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci*I@p1(x,...)
728c2ecf20Sopenharmony_ci{ ... when != x = E
738c2ecf20Sopenharmony_ci(
748c2ecf20Sopenharmony_ci*  x@p2 == NULL
758c2ecf20Sopenharmony_ci|
768c2ecf20Sopenharmony_ci*  x@p2 != NULL
778c2ecf20Sopenharmony_ci)
788c2ecf20Sopenharmony_ci  ... when any
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci@script:python depends on org@
828c2ecf20Sopenharmony_cip1 << r.p1;
838c2ecf20Sopenharmony_cip2 << r.p2;
848c2ecf20Sopenharmony_ci@@
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cicocci.print_main("iterator-bound variable",p1)
878c2ecf20Sopenharmony_cicocci.print_secs("useless NULL test",p2)
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci@script:python depends on report@
908c2ecf20Sopenharmony_cip1 << r.p1;
918c2ecf20Sopenharmony_cip2 << r.p2;
928c2ecf20Sopenharmony_ci@@
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cimsg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
958c2ecf20Sopenharmony_cicoccilib.report.print_report(p2[0], msg)
96