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