minmax.cocci 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. ///
  3. /// Check for opencoded min(), max() implementations.
  4. /// Generated patches sometimes require adding a cast to fix compile warning.
  5. /// Warnings/patches scope intentionally limited to a function body.
  6. ///
  7. // Confidence: Medium
  8. // Copyright: (C) 2021 Denis Efremov ISPRAS
  9. // Options: --no-includes --include-headers
  10. //
  11. // Keywords: min, max
  12. //
  13. virtual report
  14. virtual org
  15. virtual context
  16. virtual patch
  17. @rmax depends on !patch@
  18. identifier func;
  19. expression x, y;
  20. binary operator cmp = {>, >=};
  21. position p;
  22. @@
  23. func(...)
  24. {
  25. <...
  26. * ((x) cmp@p (y) ? (x) : (y))
  27. ...>
  28. }
  29. @rmaxif depends on !patch@
  30. identifier func;
  31. expression x, y;
  32. expression max_val;
  33. binary operator cmp = {>, >=};
  34. position p;
  35. @@
  36. func(...)
  37. {
  38. <...
  39. * if ((x) cmp@p (y)) {
  40. * max_val = (x);
  41. * } else {
  42. * max_val = (y);
  43. * }
  44. ...>
  45. }
  46. // Ignore errcode returns.
  47. @errcode@
  48. position p;
  49. identifier func;
  50. expression x;
  51. binary operator cmp = {<, <=};
  52. @@
  53. func(...)
  54. {
  55. <...
  56. return ((x) cmp@p 0 ? (x) : 0);
  57. ...>
  58. }
  59. @rmin depends on !patch@
  60. identifier func;
  61. expression x, y;
  62. binary operator cmp = {<, <=};
  63. position p != errcode.p;
  64. @@
  65. func(...)
  66. {
  67. <...
  68. * ((x) cmp@p (y) ? (x) : (y))
  69. ...>
  70. }
  71. @rminif depends on !patch@
  72. identifier func;
  73. expression x, y;
  74. expression min_val;
  75. binary operator cmp = {<, <=};
  76. position p;
  77. @@
  78. func(...)
  79. {
  80. <...
  81. * if ((x) cmp@p (y)) {
  82. * min_val = (x);
  83. * } else {
  84. * min_val = (y);
  85. * }
  86. ...>
  87. }
  88. @pmax depends on patch@
  89. identifier func;
  90. expression x, y;
  91. binary operator cmp = {>=, >};
  92. @@
  93. func(...)
  94. {
  95. <...
  96. - ((x) cmp (y) ? (x) : (y))
  97. + max(x, y)
  98. ...>
  99. }
  100. @pmaxif depends on patch@
  101. identifier func;
  102. expression x, y;
  103. expression max_val;
  104. binary operator cmp = {>=, >};
  105. @@
  106. func(...)
  107. {
  108. <...
  109. - if ((x) cmp (y)) {
  110. - max_val = x;
  111. - } else {
  112. - max_val = y;
  113. - }
  114. + max_val = max(x, y);
  115. ...>
  116. }
  117. @pmin depends on patch@
  118. identifier func;
  119. expression x, y;
  120. binary operator cmp = {<=, <};
  121. position p != errcode.p;
  122. @@
  123. func(...)
  124. {
  125. <...
  126. - ((x) cmp@p (y) ? (x) : (y))
  127. + min(x, y)
  128. ...>
  129. }
  130. @pminif depends on patch@
  131. identifier func;
  132. expression x, y;
  133. expression min_val;
  134. binary operator cmp = {<=, <};
  135. @@
  136. func(...)
  137. {
  138. <...
  139. - if ((x) cmp (y)) {
  140. - min_val = x;
  141. - } else {
  142. - min_val = y;
  143. - }
  144. + min_val = min(x, y);
  145. ...>
  146. }
  147. @script:python depends on report@
  148. p << rmax.p;
  149. @@
  150. for p0 in p:
  151. coccilib.report.print_report(p0, "WARNING opportunity for max()")
  152. @script:python depends on org@
  153. p << rmax.p;
  154. @@
  155. for p0 in p:
  156. coccilib.org.print_todo(p0, "WARNING opportunity for max()")
  157. @script:python depends on report@
  158. p << rmaxif.p;
  159. @@
  160. for p0 in p:
  161. coccilib.report.print_report(p0, "WARNING opportunity for max()")
  162. @script:python depends on org@
  163. p << rmaxif.p;
  164. @@
  165. for p0 in p:
  166. coccilib.org.print_todo(p0, "WARNING opportunity for max()")
  167. @script:python depends on report@
  168. p << rmin.p;
  169. @@
  170. for p0 in p:
  171. coccilib.report.print_report(p0, "WARNING opportunity for min()")
  172. @script:python depends on org@
  173. p << rmin.p;
  174. @@
  175. for p0 in p:
  176. coccilib.org.print_todo(p0, "WARNING opportunity for min()")
  177. @script:python depends on report@
  178. p << rminif.p;
  179. @@
  180. for p0 in p:
  181. coccilib.report.print_report(p0, "WARNING opportunity for min()")
  182. @script:python depends on org@
  183. p << rminif.p;
  184. @@
  185. for p0 in p:
  186. coccilib.org.print_todo(p0, "WARNING opportunity for min()")