Commit | Line | Data |
---|---|---|
5f66f73b DE |
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 | ||
14 | ||
15 | virtual report | |
16 | virtual org | |
17 | virtual context | |
18 | virtual patch | |
19 | ||
20 | @rmax depends on !patch@ | |
21 | identifier func; | |
22 | expression x, y; | |
23 | binary operator cmp = {>, >=}; | |
24 | position p; | |
25 | @@ | |
26 | ||
27 | func(...) | |
28 | { | |
29 | <... | |
30 | * ((x) cmp@p (y) ? (x) : (y)) | |
31 | ...> | |
32 | } | |
33 | ||
34 | @rmaxif depends on !patch@ | |
35 | identifier func; | |
36 | expression x, y; | |
37 | expression max_val; | |
38 | binary operator cmp = {>, >=}; | |
39 | position p; | |
40 | @@ | |
41 | ||
42 | func(...) | |
43 | { | |
44 | <... | |
45 | * if ((x) cmp@p (y)) { | |
46 | * max_val = (x); | |
47 | * } else { | |
48 | * max_val = (y); | |
49 | * } | |
50 | ...> | |
51 | } | |
52 | ||
e4655196 RR |
53 | // Ignore errcode returns. |
54 | @errcode@ | |
55 | position p; | |
56 | identifier func; | |
57 | expression x; | |
58 | binary operator cmp = {<, <=}; | |
59 | @@ | |
60 | ||
61 | func(...) | |
62 | { | |
63 | <... | |
64 | return ((x) cmp@p 0 ? (x) : 0); | |
65 | ...> | |
66 | } | |
67 | ||
5f66f73b DE |
68 | @rmin depends on !patch@ |
69 | identifier func; | |
70 | expression x, y; | |
71 | binary operator cmp = {<, <=}; | |
e4655196 | 72 | position p != errcode.p; |
5f66f73b DE |
73 | @@ |
74 | ||
75 | func(...) | |
76 | { | |
77 | <... | |
78 | * ((x) cmp@p (y) ? (x) : (y)) | |
79 | ...> | |
80 | } | |
81 | ||
82 | @rminif depends on !patch@ | |
83 | identifier func; | |
84 | expression x, y; | |
85 | expression min_val; | |
86 | binary operator cmp = {<, <=}; | |
87 | position p; | |
88 | @@ | |
89 | ||
90 | func(...) | |
91 | { | |
92 | <... | |
93 | * if ((x) cmp@p (y)) { | |
94 | * min_val = (x); | |
95 | * } else { | |
96 | * min_val = (y); | |
97 | * } | |
98 | ...> | |
99 | } | |
100 | ||
101 | @pmax depends on patch@ | |
102 | identifier func; | |
103 | expression x, y; | |
104 | binary operator cmp = {>=, >}; | |
105 | @@ | |
106 | ||
107 | func(...) | |
108 | { | |
109 | <... | |
110 | - ((x) cmp (y) ? (x) : (y)) | |
111 | + max(x, y) | |
112 | ...> | |
113 | } | |
114 | ||
115 | @pmaxif depends on patch@ | |
116 | identifier func; | |
117 | expression x, y; | |
118 | expression max_val; | |
119 | binary operator cmp = {>=, >}; | |
120 | @@ | |
121 | ||
122 | func(...) | |
123 | { | |
124 | <... | |
125 | - if ((x) cmp (y)) { | |
126 | - max_val = x; | |
127 | - } else { | |
128 | - max_val = y; | |
129 | - } | |
130 | + max_val = max(x, y); | |
131 | ...> | |
132 | } | |
133 | ||
134 | @pmin depends on patch@ | |
135 | identifier func; | |
136 | expression x, y; | |
137 | binary operator cmp = {<=, <}; | |
aeb300c1 | 138 | position p != errcode.p; |
5f66f73b DE |
139 | @@ |
140 | ||
141 | func(...) | |
142 | { | |
143 | <... | |
aeb300c1 | 144 | - ((x) cmp@p (y) ? (x) : (y)) |
5f66f73b DE |
145 | + min(x, y) |
146 | ...> | |
147 | } | |
148 | ||
149 | @pminif depends on patch@ | |
150 | identifier func; | |
151 | expression x, y; | |
152 | expression min_val; | |
153 | binary operator cmp = {<=, <}; | |
154 | @@ | |
155 | ||
156 | func(...) | |
157 | { | |
158 | <... | |
159 | - if ((x) cmp (y)) { | |
160 | - min_val = x; | |
161 | - } else { | |
162 | - min_val = y; | |
163 | - } | |
164 | + min_val = min(x, y); | |
165 | ...> | |
166 | } | |
167 | ||
168 | @script:python depends on report@ | |
169 | p << rmax.p; | |
170 | @@ | |
171 | ||
172 | for p0 in p: | |
173 | coccilib.report.print_report(p0, "WARNING opportunity for max()") | |
174 | ||
175 | @script:python depends on org@ | |
176 | p << rmax.p; | |
177 | @@ | |
178 | ||
179 | for p0 in p: | |
180 | coccilib.org.print_todo(p0, "WARNING opportunity for max()") | |
181 | ||
182 | @script:python depends on report@ | |
183 | p << rmaxif.p; | |
184 | @@ | |
185 | ||
186 | for p0 in p: | |
187 | coccilib.report.print_report(p0, "WARNING opportunity for max()") | |
188 | ||
189 | @script:python depends on org@ | |
190 | p << rmaxif.p; | |
191 | @@ | |
192 | ||
193 | for p0 in p: | |
194 | coccilib.org.print_todo(p0, "WARNING opportunity for max()") | |
195 | ||
196 | @script:python depends on report@ | |
197 | p << rmin.p; | |
198 | @@ | |
199 | ||
200 | for p0 in p: | |
201 | coccilib.report.print_report(p0, "WARNING opportunity for min()") | |
202 | ||
203 | @script:python depends on org@ | |
204 | p << rmin.p; | |
205 | @@ | |
206 | ||
207 | for p0 in p: | |
208 | coccilib.org.print_todo(p0, "WARNING opportunity for min()") | |
209 | ||
210 | @script:python depends on report@ | |
211 | p << rminif.p; | |
212 | @@ | |
213 | ||
214 | for p0 in p: | |
215 | coccilib.report.print_report(p0, "WARNING opportunity for min()") | |
216 | ||
217 | @script:python depends on org@ | |
218 | p << rminif.p; | |
219 | @@ | |
220 | ||
221 | for p0 in p: | |
222 | coccilib.org.print_todo(p0, "WARNING opportunity for min()") |