162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/// Compare pointer-typed values to NULL rather than 0
362306a36Sopenharmony_ci///
462306a36Sopenharmony_ci//# This makes an effort to choose between !x and x == NULL.  !x is used
562306a36Sopenharmony_ci//# if it has previously been used with the function used to initialize x.
662306a36Sopenharmony_ci//# This relies on type information.  More type information can be obtained
762306a36Sopenharmony_ci//# using the option -all_includes and the option -I to specify an
862306a36Sopenharmony_ci//# include path.
962306a36Sopenharmony_ci//
1062306a36Sopenharmony_ci// Confidence: High
1162306a36Sopenharmony_ci// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
1262306a36Sopenharmony_ci// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
1362306a36Sopenharmony_ci// URL: https://coccinelle.gitlabpages.inria.fr/website
1462306a36Sopenharmony_ci// Requires: 1.0.0
1562306a36Sopenharmony_ci// Options:
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_civirtual patch
1862306a36Sopenharmony_civirtual context
1962306a36Sopenharmony_civirtual org
2062306a36Sopenharmony_civirtual report
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci@initialize:ocaml@
2362306a36Sopenharmony_ci@@
2462306a36Sopenharmony_cilet negtable = Hashtbl.create 101
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci@depends on patch@
2762306a36Sopenharmony_ciexpression *E;
2862306a36Sopenharmony_ciidentifier f;
2962306a36Sopenharmony_ci@@
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci(
3262306a36Sopenharmony_ci  (E = f(...)) ==
3362306a36Sopenharmony_ci- 0
3462306a36Sopenharmony_ci+ NULL
3562306a36Sopenharmony_ci|
3662306a36Sopenharmony_ci  (E = f(...)) !=
3762306a36Sopenharmony_ci- 0
3862306a36Sopenharmony_ci+ NULL
3962306a36Sopenharmony_ci|
4062306a36Sopenharmony_ci- 0
4162306a36Sopenharmony_ci+ NULL
4262306a36Sopenharmony_ci  == (E = f(...))
4362306a36Sopenharmony_ci|
4462306a36Sopenharmony_ci- 0
4562306a36Sopenharmony_ci+ NULL
4662306a36Sopenharmony_ci  != (E = f(...))
4762306a36Sopenharmony_ci)
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci@t1 depends on !patch@
5162306a36Sopenharmony_ciexpression *E;
5262306a36Sopenharmony_ciidentifier f;
5362306a36Sopenharmony_ciposition p;
5462306a36Sopenharmony_ci@@
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci(
5762306a36Sopenharmony_ci  (E = f(...)) ==
5862306a36Sopenharmony_ci* 0@p
5962306a36Sopenharmony_ci|
6062306a36Sopenharmony_ci  (E = f(...)) !=
6162306a36Sopenharmony_ci* 0@p
6262306a36Sopenharmony_ci|
6362306a36Sopenharmony_ci* 0@p
6462306a36Sopenharmony_ci  == (E = f(...))
6562306a36Sopenharmony_ci|
6662306a36Sopenharmony_ci* 0@p
6762306a36Sopenharmony_ci  != (E = f(...))
6862306a36Sopenharmony_ci)
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci@script:python depends on org@
7162306a36Sopenharmony_cip << t1.p;
7262306a36Sopenharmony_ci@@
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cicoccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci@script:python depends on report@
7762306a36Sopenharmony_cip << t1.p;
7862306a36Sopenharmony_ci@@
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cicoccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci// Tests of returned values
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci@s@
8562306a36Sopenharmony_ciidentifier f;
8662306a36Sopenharmony_ciexpression E,E1;
8762306a36Sopenharmony_ci@@
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci E = f(...)
9062306a36Sopenharmony_ci ... when != E = E1
9162306a36Sopenharmony_ci !E
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci@script:ocaml depends on s@
9462306a36Sopenharmony_cif << s.f;
9562306a36Sopenharmony_ci@@
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_citry let _ = Hashtbl.find negtable f in ()
9862306a36Sopenharmony_ciwith Not_found -> Hashtbl.add negtable f ()
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci@ r disable is_zero,isnt_zero exists @
10162306a36Sopenharmony_ciexpression *E;
10262306a36Sopenharmony_ciidentifier f;
10362306a36Sopenharmony_ci@@
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ciE = f(...)
10662306a36Sopenharmony_ci...
10762306a36Sopenharmony_ci(E == 0
10862306a36Sopenharmony_ci|E != 0
10962306a36Sopenharmony_ci|0 == E
11062306a36Sopenharmony_ci|0 != E
11162306a36Sopenharmony_ci)
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci@script:ocaml@
11462306a36Sopenharmony_cif << r.f;
11562306a36Sopenharmony_ci@@
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_citry let _ = Hashtbl.find negtable f in ()
11862306a36Sopenharmony_ciwith Not_found -> include_match false
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci// This rule may lead to inconsistent path problems, if E is defined in two
12162306a36Sopenharmony_ci// places
12262306a36Sopenharmony_ci@ depends on patch disable is_zero,isnt_zero @
12362306a36Sopenharmony_ciexpression *E;
12462306a36Sopenharmony_ciexpression E1;
12562306a36Sopenharmony_ciidentifier r.f;
12662306a36Sopenharmony_ci@@
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ciE = f(...)
12962306a36Sopenharmony_ci<...
13062306a36Sopenharmony_ci(
13162306a36Sopenharmony_ci- E == 0
13262306a36Sopenharmony_ci+ !E
13362306a36Sopenharmony_ci|
13462306a36Sopenharmony_ci- E != 0
13562306a36Sopenharmony_ci+ E
13662306a36Sopenharmony_ci|
13762306a36Sopenharmony_ci- 0 == E
13862306a36Sopenharmony_ci+ !E
13962306a36Sopenharmony_ci|
14062306a36Sopenharmony_ci- 0 != E
14162306a36Sopenharmony_ci+ E
14262306a36Sopenharmony_ci)
14362306a36Sopenharmony_ci...>
14462306a36Sopenharmony_ci?E = E1
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci@t2 depends on !patch disable is_zero,isnt_zero @
14762306a36Sopenharmony_ciexpression *E;
14862306a36Sopenharmony_ciexpression E1;
14962306a36Sopenharmony_ciidentifier r.f;
15062306a36Sopenharmony_ciposition p1;
15162306a36Sopenharmony_ciposition p2;
15262306a36Sopenharmony_ci@@
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ciE = f(...)
15562306a36Sopenharmony_ci<...
15662306a36Sopenharmony_ci(
15762306a36Sopenharmony_ci* E == 0@p1
15862306a36Sopenharmony_ci|
15962306a36Sopenharmony_ci* E != 0@p2
16062306a36Sopenharmony_ci|
16162306a36Sopenharmony_ci* 0@p1 == E
16262306a36Sopenharmony_ci|
16362306a36Sopenharmony_ci* 0@p1 != E
16462306a36Sopenharmony_ci)
16562306a36Sopenharmony_ci...>
16662306a36Sopenharmony_ci?E = E1
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci@script:python depends on org@
16962306a36Sopenharmony_cip << t2.p1;
17062306a36Sopenharmony_ci@@
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cicoccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E")
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci@script:python depends on org@
17562306a36Sopenharmony_cip << t2.p2;
17662306a36Sopenharmony_ci@@
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cicoccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci@script:python depends on report@
18162306a36Sopenharmony_cip << t2.p1;
18262306a36Sopenharmony_ci@@
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cicoccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E")
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci@script:python depends on report@
18762306a36Sopenharmony_cip << t2.p2;
18862306a36Sopenharmony_ci@@
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_cicoccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci@ depends on patch disable is_zero,isnt_zero @
19362306a36Sopenharmony_ciexpression *E;
19462306a36Sopenharmony_ci@@
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci(
19762306a36Sopenharmony_ci  E ==
19862306a36Sopenharmony_ci- 0
19962306a36Sopenharmony_ci+ NULL
20062306a36Sopenharmony_ci|
20162306a36Sopenharmony_ci  E !=
20262306a36Sopenharmony_ci- 0
20362306a36Sopenharmony_ci+ NULL
20462306a36Sopenharmony_ci|
20562306a36Sopenharmony_ci- 0
20662306a36Sopenharmony_ci+ NULL
20762306a36Sopenharmony_ci  == E
20862306a36Sopenharmony_ci|
20962306a36Sopenharmony_ci- 0
21062306a36Sopenharmony_ci+ NULL
21162306a36Sopenharmony_ci  != E
21262306a36Sopenharmony_ci)
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci@ t3 depends on !patch disable is_zero,isnt_zero @
21562306a36Sopenharmony_ciexpression *E;
21662306a36Sopenharmony_ciposition p;
21762306a36Sopenharmony_ci@@
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci(
22062306a36Sopenharmony_ci* E == 0@p
22162306a36Sopenharmony_ci|
22262306a36Sopenharmony_ci* E != 0@p
22362306a36Sopenharmony_ci|
22462306a36Sopenharmony_ci* 0@p == E
22562306a36Sopenharmony_ci|
22662306a36Sopenharmony_ci* 0@p != E
22762306a36Sopenharmony_ci)
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci@script:python depends on org@
23062306a36Sopenharmony_cip << t3.p;
23162306a36Sopenharmony_ci@@
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cicoccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci@script:python depends on report@
23662306a36Sopenharmony_cip << t3.p;
23762306a36Sopenharmony_ci@@
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cicoccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
240