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@rmin depends on !patch@ 54identifier func; 55expression x, y; 56binary operator cmp = {<, <=}; 57position p; 58@@ 59 60func(...) 61{ 62 <... 63* ((x) cmp@p (y) ? (x) : (y)) 64 ...> 65} 66 67@rminif depends on !patch@ 68identifier func; 69expression x, y; 70expression min_val; 71binary operator cmp = {<, <=}; 72position p; 73@@ 74 75func(...) 76{ 77 <... 78* if ((x) cmp@p (y)) { 79* min_val = (x); 80* } else { 81* min_val = (y); 82* } 83 ...> 84} 85 86@pmax depends on patch@ 87identifier func; 88expression x, y; 89binary operator cmp = {>=, >}; 90@@ 91 92func(...) 93{ 94 <... 95- ((x) cmp (y) ? (x) : (y)) 96+ max(x, y) 97 ...> 98} 99 100@pmaxif depends on patch@ 101identifier func; 102expression x, y; 103expression max_val; 104binary operator cmp = {>=, >}; 105@@ 106 107func(...) 108{ 109 <... 110- if ((x) cmp (y)) { 111- max_val = x; 112- } else { 113- max_val = y; 114- } 115+ max_val = max(x, y); 116 ...> 117} 118 119// Don't generate patches for errcode returns. 120@errcode depends on patch@ 121position p; 122identifier func; 123expression x; 124binary operator cmp = {<, <=}; 125@@ 126 127func(...) 128{ 129 <... 130 return ((x) cmp@p 0 ? (x) : 0); 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