badzero.cocci 3.2 KB

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