Commit | Line | Data |
---|---|---|
47f67ea9 JL |
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/ | |
b5889ab7 | 13 | // Comments: Requires Coccinelle version 1.0.0-rc20 or later |
47f67ea9 JL |
14 | // Options: |
15 | ||
16 | virtual patch | |
17 | virtual context | |
18 | virtual org | |
19 | virtual report | |
20 | ||
21 | @initialize:ocaml@ | |
b5889ab7 | 22 | @@ |
47f67ea9 JL |
23 | let negtable = Hashtbl.create 101 |
24 | ||
25 | @depends on patch@ | |
26 | expression *E; | |
27 | identifier f; | |
28 | @@ | |
29 | ||
30 | ( | |
31 | (E = f(...)) == | |
32 | - 0 | |
33 | + NULL | |
34 | | | |
35 | (E = f(...)) != | |
36 | - 0 | |
37 | + NULL | |
38 | | | |
39 | - 0 | |
40 | + NULL | |
41 | == (E = f(...)) | |
42 | | | |
43 | - 0 | |
44 | + NULL | |
45 | != (E = f(...)) | |
46 | ) | |
47 | ||
48 | ||
49 | @t1 depends on !patch@ | |
50 | expression *E; | |
51 | identifier f; | |
52 | position p; | |
53 | @@ | |
54 | ||
55 | ( | |
56 | (E = f(...)) == | |
57 | * 0@p | |
58 | | | |
59 | (E = f(...)) != | |
60 | * 0@p | |
61 | | | |
62 | * 0@p | |
63 | == (E = f(...)) | |
64 | | | |
65 | * 0@p | |
66 | != (E = f(...)) | |
67 | ) | |
68 | ||
69 | @script:python depends on org@ | |
70 | p << t1.p; | |
71 | @@ | |
72 | ||
73 | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") | |
74 | ||
75 | @script:python depends on report@ | |
76 | p << t1.p; | |
77 | @@ | |
78 | ||
79 | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") | |
80 | ||
81 | // Tests of returned values | |
82 | ||
83 | @s@ | |
84 | identifier f; | |
85 | expression E,E1; | |
86 | @@ | |
87 | ||
88 | E = f(...) | |
89 | ... when != E = E1 | |
90 | !E | |
91 | ||
92 | @script:ocaml depends on s@ | |
93 | f << s.f; | |
94 | @@ | |
95 | ||
96 | try let _ = Hashtbl.find negtable f in () | |
97 | with Not_found -> Hashtbl.add negtable f () | |
98 | ||
99 | @ r disable is_zero,isnt_zero exists @ | |
100 | expression *E; | |
101 | identifier f; | |
102 | @@ | |
103 | ||
104 | E = f(...) | |
105 | ... | |
106 | (E == 0 | |
107 | |E != 0 | |
108 | |0 == E | |
109 | |0 != E | |
110 | ) | |
111 | ||
112 | @script:ocaml@ | |
113 | f << r.f; | |
114 | @@ | |
115 | ||
116 | try let _ = Hashtbl.find negtable f in () | |
117 | with Not_found -> include_match false | |
118 | ||
119 | // This rule may lead to inconsistent path problems, if E is defined in two | |
120 | // places | |
121 | @ depends on patch disable is_zero,isnt_zero @ | |
122 | expression *E; | |
123 | expression E1; | |
124 | identifier r.f; | |
125 | @@ | |
126 | ||
127 | E = f(...) | |
128 | <... | |
129 | ( | |
130 | - E == 0 | |
131 | + !E | |
132 | | | |
133 | - E != 0 | |
134 | + E | |
135 | | | |
136 | - 0 == E | |
137 | + !E | |
138 | | | |
139 | - 0 != E | |
140 | + E | |
141 | ) | |
142 | ...> | |
143 | ?E = E1 | |
144 | ||
145 | @t2 depends on !patch disable is_zero,isnt_zero @ | |
146 | expression *E; | |
147 | expression E1; | |
148 | identifier r.f; | |
149 | position p1; | |
150 | position p2; | |
151 | @@ | |
152 | ||
153 | E = f(...) | |
154 | <... | |
155 | ( | |
156 | * E == 0@p1 | |
157 | | | |
158 | * E != 0@p2 | |
159 | | | |
160 | * 0@p1 == E | |
161 | | | |
162 | * 0@p1 != E | |
163 | ) | |
164 | ...> | |
165 | ?E = E1 | |
166 | ||
167 | @script:python depends on org@ | |
168 | p << t2.p1; | |
169 | @@ | |
170 | ||
171 | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E") | |
172 | ||
173 | @script:python depends on org@ | |
174 | p << t2.p2; | |
175 | @@ | |
176 | ||
177 | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") | |
178 | ||
179 | @script:python depends on report@ | |
180 | p << t2.p1; | |
181 | @@ | |
182 | ||
183 | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E") | |
184 | ||
185 | @script:python depends on report@ | |
186 | p << t2.p2; | |
187 | @@ | |
188 | ||
189 | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") | |
190 | ||
191 | @ depends on patch disable is_zero,isnt_zero @ | |
192 | expression *E; | |
193 | @@ | |
194 | ||
195 | ( | |
196 | E == | |
197 | - 0 | |
198 | + NULL | |
199 | | | |
200 | E != | |
201 | - 0 | |
202 | + NULL | |
203 | | | |
204 | - 0 | |
205 | + NULL | |
206 | == E | |
207 | | | |
208 | - 0 | |
209 | + NULL | |
210 | != E | |
211 | ) | |
212 | ||
213 | @ t3 depends on !patch disable is_zero,isnt_zero @ | |
214 | expression *E; | |
215 | position p; | |
216 | @@ | |
217 | ||
218 | ( | |
219 | * E == 0@p | |
220 | | | |
221 | * E != 0@p | |
222 | | | |
223 | * 0@p == E | |
224 | | | |
225 | * 0@p != E | |
226 | ) | |
227 | ||
228 | @script:python depends on org@ | |
229 | p << t3.p; | |
230 | @@ | |
231 | ||
232 | coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") | |
233 | ||
234 | @script:python depends on report@ | |
235 | p << t3.p; | |
236 | @@ | |
237 | ||
238 | coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") |