15f66f73bSDenis Efremov// SPDX-License-Identifier: GPL-2.0-only
25f66f73bSDenis Efremov///
35f66f73bSDenis Efremov/// Check for opencoded min(), max() implementations.
45f66f73bSDenis Efremov/// Generated patches sometimes require adding a cast to fix compile warning.
55f66f73bSDenis Efremov/// Warnings/patches scope intentionally limited to a function body.
65f66f73bSDenis Efremov///
75f66f73bSDenis Efremov// Confidence: Medium
85f66f73bSDenis Efremov// Copyright: (C) 2021 Denis Efremov ISPRAS
95f66f73bSDenis Efremov// Options: --no-includes --include-headers
105f66f73bSDenis Efremov//
115f66f73bSDenis Efremov// Keywords: min, max
125f66f73bSDenis Efremov//
135f66f73bSDenis Efremov
145f66f73bSDenis Efremov
155f66f73bSDenis Efremovvirtual report
165f66f73bSDenis Efremovvirtual org
175f66f73bSDenis Efremovvirtual context
185f66f73bSDenis Efremovvirtual patch
195f66f73bSDenis Efremov
205f66f73bSDenis Efremov@rmax depends on !patch@
215f66f73bSDenis Efremovidentifier func;
225f66f73bSDenis Efremovexpression x, y;
235f66f73bSDenis Efremovbinary operator cmp = {>, >=};
245f66f73bSDenis Efremovposition p;
255f66f73bSDenis Efremov@@
265f66f73bSDenis Efremov
275f66f73bSDenis Efremovfunc(...)
285f66f73bSDenis Efremov{
295f66f73bSDenis Efremov	<...
305f66f73bSDenis Efremov*	((x) cmp@p (y) ? (x) : (y))
315f66f73bSDenis Efremov	...>
325f66f73bSDenis Efremov}
335f66f73bSDenis Efremov
345f66f73bSDenis Efremov@rmaxif depends on !patch@
355f66f73bSDenis Efremovidentifier func;
365f66f73bSDenis Efremovexpression x, y;
375f66f73bSDenis Efremovexpression max_val;
385f66f73bSDenis Efremovbinary operator cmp = {>, >=};
395f66f73bSDenis Efremovposition p;
405f66f73bSDenis Efremov@@
415f66f73bSDenis Efremov
425f66f73bSDenis Efremovfunc(...)
435f66f73bSDenis Efremov{
445f66f73bSDenis Efremov	<...
455f66f73bSDenis Efremov*	if ((x) cmp@p (y)) {
465f66f73bSDenis Efremov*		max_val = (x);
475f66f73bSDenis Efremov*	} else {
485f66f73bSDenis Efremov*		max_val = (y);
495f66f73bSDenis Efremov*	}
505f66f73bSDenis Efremov	...>
515f66f73bSDenis Efremov}
525f66f73bSDenis Efremov
535f66f73bSDenis Efremov@rmin depends on !patch@
545f66f73bSDenis Efremovidentifier func;
555f66f73bSDenis Efremovexpression x, y;
565f66f73bSDenis Efremovbinary operator cmp = {<, <=};
575f66f73bSDenis Efremovposition p;
585f66f73bSDenis Efremov@@
595f66f73bSDenis Efremov
605f66f73bSDenis Efremovfunc(...)
615f66f73bSDenis Efremov{
625f66f73bSDenis Efremov	<...
635f66f73bSDenis Efremov*	((x) cmp@p (y) ? (x) : (y))
645f66f73bSDenis Efremov	...>
655f66f73bSDenis Efremov}
665f66f73bSDenis Efremov
675f66f73bSDenis Efremov@rminif depends on !patch@
685f66f73bSDenis Efremovidentifier func;
695f66f73bSDenis Efremovexpression x, y;
705f66f73bSDenis Efremovexpression min_val;
715f66f73bSDenis Efremovbinary operator cmp = {<, <=};
725f66f73bSDenis Efremovposition p;
735f66f73bSDenis Efremov@@
745f66f73bSDenis Efremov
755f66f73bSDenis Efremovfunc(...)
765f66f73bSDenis Efremov{
775f66f73bSDenis Efremov	<...
785f66f73bSDenis Efremov*	if ((x) cmp@p (y)) {
795f66f73bSDenis Efremov*		min_val = (x);
805f66f73bSDenis Efremov*	} else {
815f66f73bSDenis Efremov*		min_val = (y);
825f66f73bSDenis Efremov*	}
835f66f73bSDenis Efremov	...>
845f66f73bSDenis Efremov}
855f66f73bSDenis Efremov
865f66f73bSDenis Efremov@pmax depends on patch@
875f66f73bSDenis Efremovidentifier func;
885f66f73bSDenis Efremovexpression x, y;
895f66f73bSDenis Efremovbinary operator cmp = {>=, >};
905f66f73bSDenis Efremov@@
915f66f73bSDenis Efremov
925f66f73bSDenis Efremovfunc(...)
935f66f73bSDenis Efremov{
945f66f73bSDenis Efremov	<...
955f66f73bSDenis Efremov-	((x) cmp (y) ? (x) : (y))
965f66f73bSDenis Efremov+	max(x, y)
975f66f73bSDenis Efremov	...>
985f66f73bSDenis Efremov}
995f66f73bSDenis Efremov
1005f66f73bSDenis Efremov@pmaxif depends on patch@
1015f66f73bSDenis Efremovidentifier func;
1025f66f73bSDenis Efremovexpression x, y;
1035f66f73bSDenis Efremovexpression max_val;
1045f66f73bSDenis Efremovbinary operator cmp = {>=, >};
1055f66f73bSDenis Efremov@@
1065f66f73bSDenis Efremov
1075f66f73bSDenis Efremovfunc(...)
1085f66f73bSDenis Efremov{
1095f66f73bSDenis Efremov	<...
1105f66f73bSDenis Efremov-	if ((x) cmp (y)) {
1115f66f73bSDenis Efremov-		max_val = x;
1125f66f73bSDenis Efremov-	} else {
1135f66f73bSDenis Efremov-		max_val = y;
1145f66f73bSDenis Efremov-	}
1155f66f73bSDenis Efremov+	max_val = max(x, y);
1165f66f73bSDenis Efremov	...>
1175f66f73bSDenis Efremov}
1185f66f73bSDenis Efremov
119*aeb300c1SDenis Efremov// Don't generate patches for errcode returns.
120*aeb300c1SDenis Efremov@errcode depends on patch@
121*aeb300c1SDenis Efremovposition p;
1225f66f73bSDenis Efremovidentifier func;
123*aeb300c1SDenis Efremovexpression x;
124*aeb300c1SDenis Efremovbinary operator cmp = {<, <=};
1255f66f73bSDenis Efremov@@
1265f66f73bSDenis Efremov
1275f66f73bSDenis Efremovfunc(...)
1285f66f73bSDenis Efremov{
1295f66f73bSDenis Efremov	<...
130*aeb300c1SDenis Efremov	return ((x) cmp@p 0 ? (x) : 0);
131*aeb300c1SDenis Efremov	...>
132*aeb300c1SDenis Efremov}
133*aeb300c1SDenis Efremov
134*aeb300c1SDenis Efremov@pmin depends on patch@
135*aeb300c1SDenis Efremovidentifier func;
136*aeb300c1SDenis Efremovexpression x, y;
137*aeb300c1SDenis Efremovbinary operator cmp = {<=, <};
138*aeb300c1SDenis Efremovposition p != errcode.p;
139*aeb300c1SDenis Efremov@@
140*aeb300c1SDenis Efremov
141*aeb300c1SDenis Efremovfunc(...)
142*aeb300c1SDenis Efremov{
143*aeb300c1SDenis Efremov	<...
144*aeb300c1SDenis Efremov-	((x) cmp@p (y) ? (x) : (y))
1455f66f73bSDenis Efremov+	min(x, y)
1465f66f73bSDenis Efremov	...>
1475f66f73bSDenis Efremov}
1485f66f73bSDenis Efremov
1495f66f73bSDenis Efremov@pminif depends on patch@
1505f66f73bSDenis Efremovidentifier func;
1515f66f73bSDenis Efremovexpression x, y;
1525f66f73bSDenis Efremovexpression min_val;
1535f66f73bSDenis Efremovbinary operator cmp = {<=, <};
1545f66f73bSDenis Efremov@@
1555f66f73bSDenis Efremov
1565f66f73bSDenis Efremovfunc(...)
1575f66f73bSDenis Efremov{
1585f66f73bSDenis Efremov	<...
1595f66f73bSDenis Efremov-	if ((x) cmp (y)) {
1605f66f73bSDenis Efremov-		min_val = x;
1615f66f73bSDenis Efremov-	} else {
1625f66f73bSDenis Efremov-		min_val = y;
1635f66f73bSDenis Efremov-	}
1645f66f73bSDenis Efremov+	min_val = min(x, y);
1655f66f73bSDenis Efremov	...>
1665f66f73bSDenis Efremov}
1675f66f73bSDenis Efremov
1685f66f73bSDenis Efremov@script:python depends on report@
1695f66f73bSDenis Efremovp << rmax.p;
1705f66f73bSDenis Efremov@@
1715f66f73bSDenis Efremov
1725f66f73bSDenis Efremovfor p0 in p:
1735f66f73bSDenis Efremov	coccilib.report.print_report(p0, "WARNING opportunity for max()")
1745f66f73bSDenis Efremov
1755f66f73bSDenis Efremov@script:python depends on org@
1765f66f73bSDenis Efremovp << rmax.p;
1775f66f73bSDenis Efremov@@
1785f66f73bSDenis Efremov
1795f66f73bSDenis Efremovfor p0 in p:
1805f66f73bSDenis Efremov	coccilib.org.print_todo(p0, "WARNING opportunity for max()")
1815f66f73bSDenis Efremov
1825f66f73bSDenis Efremov@script:python depends on report@
1835f66f73bSDenis Efremovp << rmaxif.p;
1845f66f73bSDenis Efremov@@
1855f66f73bSDenis Efremov
1865f66f73bSDenis Efremovfor p0 in p:
1875f66f73bSDenis Efremov	coccilib.report.print_report(p0, "WARNING opportunity for max()")
1885f66f73bSDenis Efremov
1895f66f73bSDenis Efremov@script:python depends on org@
1905f66f73bSDenis Efremovp << rmaxif.p;
1915f66f73bSDenis Efremov@@
1925f66f73bSDenis Efremov
1935f66f73bSDenis Efremovfor p0 in p:
1945f66f73bSDenis Efremov	coccilib.org.print_todo(p0, "WARNING opportunity for max()")
1955f66f73bSDenis Efremov
1965f66f73bSDenis Efremov@script:python depends on report@
1975f66f73bSDenis Efremovp << rmin.p;
1985f66f73bSDenis Efremov@@
1995f66f73bSDenis Efremov
2005f66f73bSDenis Efremovfor p0 in p:
2015f66f73bSDenis Efremov	coccilib.report.print_report(p0, "WARNING opportunity for min()")
2025f66f73bSDenis Efremov
2035f66f73bSDenis Efremov@script:python depends on org@
2045f66f73bSDenis Efremovp << rmin.p;
2055f66f73bSDenis Efremov@@
2065f66f73bSDenis Efremov
2075f66f73bSDenis Efremovfor p0 in p:
2085f66f73bSDenis Efremov	coccilib.org.print_todo(p0, "WARNING opportunity for min()")
2095f66f73bSDenis Efremov
2105f66f73bSDenis Efremov@script:python depends on report@
2115f66f73bSDenis Efremovp << rminif.p;
2125f66f73bSDenis Efremov@@
2135f66f73bSDenis Efremov
2145f66f73bSDenis Efremovfor p0 in p:
2155f66f73bSDenis Efremov	coccilib.report.print_report(p0, "WARNING opportunity for min()")
2165f66f73bSDenis Efremov
2175f66f73bSDenis Efremov@script:python depends on org@
2185f66f73bSDenis Efremovp << rminif.p;
2195f66f73bSDenis Efremov@@
2205f66f73bSDenis Efremov
2215f66f73bSDenis Efremovfor p0 in p:
2225f66f73bSDenis Efremov	coccilib.org.print_todo(p0, "WARNING opportunity for min()")
223