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