badzero.cocci 3.2 KB

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