1/// Compare pointer-typed values to NULL rather than 0
2///
3//# This makes an effort to choose between !x and x == NULL.  !x is used
4//# if it has previously been used with the function used to initialize x.
5//# This relies on type information.  More type information can be obtained
6//# using the option -all_includes and the option -I to specify an
7//# include path.
8//
9// Confidence: High
10// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
11// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
12// URL: http://coccinelle.lip6.fr/
13// Requires: 1.0.0
14// Options:
15//
16// SPDX-License-Identifier:	GPL-2.0
17//
18
19virtual patch
20virtual context
21virtual org
22virtual report
23
24@initialize:ocaml@
25@@
26let negtable = Hashtbl.create 101
27
28@depends on patch@
29expression *E;
30identifier f;
31@@
32
33(
34  (E = f(...)) ==
35- 0
36+ NULL
37|
38  (E = f(...)) !=
39- 0
40+ NULL
41|
42- 0
43+ NULL
44  == (E = f(...))
45|
46- 0
47+ NULL
48  != (E = f(...))
49)
50
51
52@t1 depends on !patch@
53expression *E;
54identifier f;
55position p;
56@@
57
58(
59  (E = f(...)) ==
60* 0@p
61|
62  (E = f(...)) !=
63* 0@p
64|
65* 0@p
66  == (E = f(...))
67|
68* 0@p
69  != (E = f(...))
70)
71
72@script:python depends on org@
73p << t1.p;
74@@
75
76coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
77
78@script:python depends on report@
79p << t1.p;
80@@
81
82coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
83
84// Tests of returned values
85
86@s@
87identifier f;
88expression E,E1;
89@@
90
91 E = f(...)
92 ... when != E = E1
93 !E
94
95@script:ocaml depends on s@
96f << s.f;
97@@
98
99try let _ = Hashtbl.find negtable f in ()
100with Not_found -> Hashtbl.add negtable f ()
101
102@ r disable is_zero,isnt_zero exists @
103expression *E;
104identifier f;
105@@
106
107E = f(...)
108...
109(E == 0
110|E != 0
111|0 == E
112|0 != E
113)
114
115@script:ocaml@
116f << r.f;
117@@
118
119try let _ = Hashtbl.find negtable f in ()
120with Not_found -> include_match false
121
122// This rule may lead to inconsistent path problems, if E is defined in two
123// places
124@ depends on patch disable is_zero,isnt_zero @
125expression *E;
126expression E1;
127identifier r.f;
128@@
129
130E = f(...)
131<...
132(
133- E == 0
134+ !E
135|
136- E != 0
137+ E
138|
139- 0 == E
140+ !E
141|
142- 0 != E
143+ E
144)
145...>
146?E = E1
147
148@t2 depends on !patch disable is_zero,isnt_zero @
149expression *E;
150expression E1;
151identifier r.f;
152position p1;
153position p2;
154@@
155
156E = f(...)
157<...
158(
159* E == 0@p1
160|
161* E != 0@p2
162|
163* 0@p1 == E
164|
165* 0@p1 != E
166)
167...>
168?E = E1
169
170@script:python depends on org@
171p << t2.p1;
172@@
173
174coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E")
175
176@script:python depends on org@
177p << t2.p2;
178@@
179
180coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
181
182@script:python depends on report@
183p << t2.p1;
184@@
185
186coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E")
187
188@script:python depends on report@
189p << t2.p2;
190@@
191
192coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
193
194@ depends on patch disable is_zero,isnt_zero @
195expression *E;
196@@
197
198(
199  E ==
200- 0
201+ NULL
202|
203  E !=
204- 0
205+ NULL
206|
207- 0
208+ NULL
209  == E
210|
211- 0
212+ NULL
213  != E
214)
215
216@ t3 depends on !patch disable is_zero,isnt_zero @
217expression *E;
218position p;
219@@
220
221(
222* E == 0@p
223|
224* E != 0@p
225|
226* 0@p == E
227|
228* 0@p != E
229)
230
231@script:python depends on org@
232p << t3.p;
233@@
234
235coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
236
237@script:python depends on report@
238p << t3.p;
239@@
240
241coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
242