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