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