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