0001 // SPDX-License-Identifier: GPL-2.0-only
0002 ///
0003 /// Check for opencoded min(), max() implementations.
0004 /// Generated patches sometimes require adding a cast to fix compile warning.
0005 /// Warnings/patches scope intentionally limited to a function body.
0006 ///
0007 // Confidence: Medium
0008 // Copyright: (C) 2021 Denis Efremov ISPRAS
0009 // Options: --no-includes --include-headers
0010 //
0011 // Keywords: min, max
0012 //
0013
0014
0015 virtual report
0016 virtual org
0017 virtual context
0018 virtual patch
0019
0020 @rmax depends on !patch@
0021 identifier func;
0022 expression x, y;
0023 binary operator cmp = {>, >=};
0024 position p;
0025 @@
0026
0027 func(...)
0028 {
0029 <...
0030 * ((x) cmp@p (y) ? (x) : (y))
0031 ...>
0032 }
0033
0034 @rmaxif depends on !patch@
0035 identifier func;
0036 expression x, y;
0037 expression max_val;
0038 binary operator cmp = {>, >=};
0039 position p;
0040 @@
0041
0042 func(...)
0043 {
0044 <...
0045 * if ((x) cmp@p (y)) {
0046 * max_val = (x);
0047 * } else {
0048 * max_val = (y);
0049 * }
0050 ...>
0051 }
0052
0053 @rmin depends on !patch@
0054 identifier func;
0055 expression x, y;
0056 binary operator cmp = {<, <=};
0057 position p;
0058 @@
0059
0060 func(...)
0061 {
0062 <...
0063 * ((x) cmp@p (y) ? (x) : (y))
0064 ...>
0065 }
0066
0067 @rminif depends on !patch@
0068 identifier func;
0069 expression x, y;
0070 expression min_val;
0071 binary operator cmp = {<, <=};
0072 position p;
0073 @@
0074
0075 func(...)
0076 {
0077 <...
0078 * if ((x) cmp@p (y)) {
0079 * min_val = (x);
0080 * } else {
0081 * min_val = (y);
0082 * }
0083 ...>
0084 }
0085
0086 @pmax depends on patch@
0087 identifier func;
0088 expression x, y;
0089 binary operator cmp = {>=, >};
0090 @@
0091
0092 func(...)
0093 {
0094 <...
0095 - ((x) cmp (y) ? (x) : (y))
0096 + max(x, y)
0097 ...>
0098 }
0099
0100 @pmaxif depends on patch@
0101 identifier func;
0102 expression x, y;
0103 expression max_val;
0104 binary operator cmp = {>=, >};
0105 @@
0106
0107 func(...)
0108 {
0109 <...
0110 - if ((x) cmp (y)) {
0111 - max_val = x;
0112 - } else {
0113 - max_val = y;
0114 - }
0115 + max_val = max(x, y);
0116 ...>
0117 }
0118
0119 // Don't generate patches for errcode returns.
0120 @errcode depends on patch@
0121 position p;
0122 identifier func;
0123 expression x;
0124 binary operator cmp = {<, <=};
0125 @@
0126
0127 func(...)
0128 {
0129 <...
0130 return ((x) cmp@p 0 ? (x) : 0);
0131 ...>
0132 }
0133
0134 @pmin depends on patch@
0135 identifier func;
0136 expression x, y;
0137 binary operator cmp = {<=, <};
0138 position p != errcode.p;
0139 @@
0140
0141 func(...)
0142 {
0143 <...
0144 - ((x) cmp@p (y) ? (x) : (y))
0145 + min(x, y)
0146 ...>
0147 }
0148
0149 @pminif depends on patch@
0150 identifier func;
0151 expression x, y;
0152 expression min_val;
0153 binary operator cmp = {<=, <};
0154 @@
0155
0156 func(...)
0157 {
0158 <...
0159 - if ((x) cmp (y)) {
0160 - min_val = x;
0161 - } else {
0162 - min_val = y;
0163 - }
0164 + min_val = min(x, y);
0165 ...>
0166 }
0167
0168 @script:python depends on report@
0169 p << rmax.p;
0170 @@
0171
0172 for p0 in p:
0173 coccilib.report.print_report(p0, "WARNING opportunity for max()")
0174
0175 @script:python depends on org@
0176 p << rmax.p;
0177 @@
0178
0179 for p0 in p:
0180 coccilib.org.print_todo(p0, "WARNING opportunity for max()")
0181
0182 @script:python depends on report@
0183 p << rmaxif.p;
0184 @@
0185
0186 for p0 in p:
0187 coccilib.report.print_report(p0, "WARNING opportunity for max()")
0188
0189 @script:python depends on org@
0190 p << rmaxif.p;
0191 @@
0192
0193 for p0 in p:
0194 coccilib.org.print_todo(p0, "WARNING opportunity for max()")
0195
0196 @script:python depends on report@
0197 p << rmin.p;
0198 @@
0199
0200 for p0 in p:
0201 coccilib.report.print_report(p0, "WARNING opportunity for min()")
0202
0203 @script:python depends on org@
0204 p << rmin.p;
0205 @@
0206
0207 for p0 in p:
0208 coccilib.org.print_todo(p0, "WARNING opportunity for min()")
0209
0210 @script:python depends on report@
0211 p << rminif.p;
0212 @@
0213
0214 for p0 in p:
0215 coccilib.report.print_report(p0, "WARNING opportunity for min()")
0216
0217 @script:python depends on org@
0218 p << rminif.p;
0219 @@
0220
0221 for p0 in p:
0222 coccilib.org.print_todo(p0, "WARNING opportunity for min()")