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. @rmin depends on !patch@
  47. identifier func;
  48. expression x, y;
  49. binary operator cmp = {<, <=};
  50. position p;
  51. @@
  52. func(...)
  53. {
  54. <...
  55. * ((x) cmp@p (y) ? (x) : (y))
  56. ...>
  57. }
  58. @rminif depends on !patch@
  59. identifier func;
  60. expression x, y;
  61. expression min_val;
  62. binary operator cmp = {<, <=};
  63. position p;
  64. @@
  65. func(...)
  66. {
  67. <...
  68. * if ((x) cmp@p (y)) {
  69. * min_val = (x);
  70. * } else {
  71. * min_val = (y);
  72. * }
  73. ...>
  74. }
  75. @pmax depends on patch@
  76. identifier func;
  77. expression x, y;
  78. binary operator cmp = {>=, >};
  79. @@
  80. func(...)
  81. {
  82. <...
  83. - ((x) cmp (y) ? (x) : (y))
  84. + max(x, y)
  85. ...>
  86. }
  87. @pmaxif depends on patch@
  88. identifier func;
  89. expression x, y;
  90. expression max_val;
  91. binary operator cmp = {>=, >};
  92. @@
  93. func(...)
  94. {
  95. <...
  96. - if ((x) cmp (y)) {
  97. - max_val = x;
  98. - } else {
  99. - max_val = y;
  100. - }
  101. + max_val = max(x, y);
  102. ...>
  103. }
  104. // Don't generate patches for errcode returns.
  105. @errcode depends on patch@
  106. position p;
  107. identifier func;
  108. expression x;
  109. binary operator cmp = {<, <=};
  110. @@
  111. func(...)
  112. {
  113. <...
  114. return ((x) cmp@p 0 ? (x) : 0);
  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()")