xref: /linux/scripts/coccinelle/misc/minmax.cocci (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
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
15virtual report
16virtual org
17virtual context
18virtual patch
19
20@max_candidate disable not_int1, not_int2, neg_if_exp@
21expression E1, E2, E3, E4;
22binary operator cmp = {>, >=};
23@@
24
25	E1 cmp E2 ? E3 : E4
26
27@min_candidate disable not_int1, not_int2, neg_if_exp@
28expression E1, E2, E3, E4;
29binary operator cmp = {<, <=};
30@@
31
32	E1 cmp E2 ? E3 : E4
33
34@rmax depends on !patch && max_candidate disable not_int1, not_int2, neg_if_exp@
35identifier func;
36expression x, y;
37binary operator cmp = {>, >=};
38position p;
39@@
40
41func(...)
42{
43	<...
44*	(x) cmp@p (y) ? (x) : (y)
45	...>
46}
47
48@maxif_candidate disable not_int1, not_int2, neg_if@
49expression x, y;
50expression max_val;
51binary operator cmp = {>, >=};
52@@
53
54if ((x) cmp (y)) {
55        max_val = (x);
56} else {
57        max_val = (y);
58}
59
60@rmaxif depends on !patch && maxif_candidate disable not_int1, not_int2, neg_if@
61identifier func;
62expression x, y;
63expression max_val;
64binary operator cmp = {>, >=};
65position p;
66@@
67
68func(...)
69{
70	<...
71*	if ((x) cmp@p (y)) {
72*		max_val = (x);
73*	} else {
74*		max_val = (y);
75*	}
76	...>
77}
78
79// Ignore errcode returns.
80@errcode depends on min_candidate disable not_int1, not_int2, neg_if_exp@
81position p;
82identifier func;
83expression x;
84binary operator cmp = {<, <=};
85@@
86
87func(...)
88{
89	<...
90	return ((x) cmp@p 0 ? (x) : 0);
91	...>
92}
93
94@rmin depends on !patch && min_candidate disable not_int1, not_int2, neg_if_exp@
95identifier func;
96expression x, y;
97binary operator cmp = {<, <=};
98position p != errcode.p;
99@@
100
101func(...)
102{
103	<...
104*	(x) cmp@p (y) ? (x) : (y)
105	...>
106}
107
108@minif_candidate disable not_int1, not_int2, neg_if@
109expression x, y;
110expression min_val;
111binary operator cmp = {<, <=};
112@@
113
114if ((x) cmp (y)) {
115        min_val = (x);
116} else {
117        min_val = (y);
118}
119
120@rminif depends on !patch && minif_candidate disable not_int1, not_int2, neg_if@
121identifier func;
122expression x, y;
123expression min_val;
124binary operator cmp = {<, <=};
125position p;
126@@
127
128func(...)
129{
130	<...
131*	if ((x) cmp@p (y)) {
132*		min_val = (x);
133*	} else {
134*		min_val = (y);
135*	}
136	...>
137}
138
139@pmax depends on patch && max_candidate disable not_int1, not_int2, neg_if_exp@
140identifier func;
141expression x, y;
142binary operator cmp = {>=, >};
143@@
144
145func(...)
146{
147	<...
148-	((x) cmp (y) ? (x) : (y))
149+	max(x, y)
150	...>
151}
152
153@pmaxif depends on patch && maxif_candidate disable not_int1, not_int2, neg_if@
154identifier func;
155expression x, y;
156expression max_val;
157binary operator cmp = {>=, >};
158@@
159
160func(...)
161{
162	<...
163-	if ((x) cmp (y)) {
164-		max_val = x;
165-	} else {
166-		max_val = y;
167-	}
168+	max_val = max(x, y);
169	...>
170}
171
172@pmin depends on patch && min_candidate disable not_int1, not_int2, neg_if_exp@
173identifier func;
174expression x, y;
175binary operator cmp = {<=, <};
176position p != errcode.p;
177@@
178
179func(...)
180{
181	<...
182-	((x) cmp@p (y) ? (x) : (y))
183+	min(x, y)
184	...>
185}
186
187@pminif depends on patch && minif_candidate disable not_int1, not_int2, neg_if@
188identifier func;
189expression x, y;
190expression min_val;
191binary operator cmp = {<=, <};
192@@
193
194func(...)
195{
196	<...
197-	if ((x) cmp (y)) {
198-		min_val = x;
199-	} else {
200-		min_val = y;
201-	}
202+	min_val = min(x, y);
203	...>
204}
205
206@script:python depends on report@
207p << rmax.p;
208@@
209
210for p0 in p:
211	coccilib.report.print_report(p0, "WARNING opportunity for max()")
212
213@script:python depends on org@
214p << rmax.p;
215@@
216
217for p0 in p:
218	coccilib.org.print_todo(p0, "WARNING opportunity for max()")
219
220@script:python depends on report@
221p << rmaxif.p;
222@@
223
224for p0 in p:
225	coccilib.report.print_report(p0, "WARNING opportunity for max()")
226
227@script:python depends on org@
228p << rmaxif.p;
229@@
230
231for p0 in p:
232	coccilib.org.print_todo(p0, "WARNING opportunity for max()")
233
234@script:python depends on report@
235p << rmin.p;
236@@
237
238for p0 in p:
239	coccilib.report.print_report(p0, "WARNING opportunity for min()")
240
241@script:python depends on org@
242p << rmin.p;
243@@
244
245for p0 in p:
246	coccilib.org.print_todo(p0, "WARNING opportunity for min()")
247
248@script:python depends on report@
249p << rminif.p;
250@@
251
252for p0 in p:
253	coccilib.report.print_report(p0, "WARNING opportunity for min()")
254
255@script:python depends on org@
256p << rminif.p;
257@@
258
259for p0 in p:
260	coccilib.org.print_todo(p0, "WARNING opportunity for min()")
261