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