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: Requires Coccinelle version 1.0.0-rc20 or later 14// Options: 15 16virtual patch 17virtual context 18virtual org 19virtual report 20 21@initialize:ocaml@ 22@@ 23let negtable = Hashtbl.create 101 24 25@depends on patch@ 26expression *E; 27identifier 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@ 50expression *E; 51identifier f; 52position 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@ 70p << t1.p; 71@@ 72 73coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") 74 75@script:python depends on report@ 76p << t1.p; 77@@ 78 79coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") 80 81// Tests of returned values 82 83@s@ 84identifier f; 85expression E,E1; 86@@ 87 88 E = f(...) 89 ... when != E = E1 90 !E 91 92@script:ocaml depends on s@ 93f << s.f; 94@@ 95 96try let _ = Hashtbl.find negtable f in () 97with Not_found -> Hashtbl.add negtable f () 98 99@ r disable is_zero,isnt_zero exists @ 100expression *E; 101identifier f; 102@@ 103 104E = f(...) 105... 106(E == 0 107|E != 0 108|0 == E 109|0 != E 110) 111 112@script:ocaml@ 113f << r.f; 114@@ 115 116try let _ = Hashtbl.find negtable f in () 117with 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 @ 122expression *E; 123expression E1; 124identifier r.f; 125@@ 126 127E = 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 @ 146expression *E; 147expression E1; 148identifier r.f; 149position p1; 150position p2; 151@@ 152 153E = 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@ 168p << t2.p1; 169@@ 170 171coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E") 172 173@script:python depends on org@ 174p << t2.p2; 175@@ 176 177coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") 178 179@script:python depends on report@ 180p << t2.p1; 181@@ 182 183coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E") 184 185@script:python depends on report@ 186p << t2.p2; 187@@ 188 189coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") 190 191@ depends on patch disable is_zero,isnt_zero @ 192expression *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 @ 214expression *E; 215position 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@ 229p << t3.p; 230@@ 231 232coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") 233 234@script:python depends on report@ 235p << t3.p; 236@@ 237 238coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") 239