summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Perches <joe@perches.com>2011-07-25 17:13:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 20:57:16 -0700
commit7d2367af0b09f8028dc5c1b1919bb82d141c2afb (patch)
treee2645027cae1b716443e2659bda5364cb101d4e0
parent27c46a2546c75c6814562e85b751e3d64c188ad5 (diff)
checkpatch: suggest using min_t or max_t
A common issue with min() or max() is using a cast on one or both of the arguments when using min_t/max_t could be better. Add cast detection to uses of min/max and suggest an appropriate use of min_t or max_t instead. Caveat: This only works for min() or max() on a single line. It does not find min() or max() split across multiple lines. This does find: min((u32)foo, bar); But it does not find: max((unsigned long)foo, bar); Suggested-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Joe Perches <joe@perches.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rwxr-xr-xscripts/checkpatch.pl35
1 files changed, 35 insertions, 0 deletions
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index b0aa2c680593..5ba62d8b5e52 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -268,6 +268,20 @@ sub build_types {
}
build_types();
+our $match_balanced_parentheses = qr/(\((?:[^\(\)]+|(-1))*\))/;
+
+our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
+our $LvalOrFunc = qr{($Lval)\s*($match_balanced_parentheses{0,1})\s*};
+
+sub deparenthesize {
+ my ($string) = @_;
+ return "" if (!defined($string));
+ $string =~ s@^\s*\(\s*@@g;
+ $string =~ s@\s*\)\s*$@@g;
+ $string =~ s@\s+@ @g;
+ return $string;
+}
+
$chk_signoff = 0 if ($file);
my @dep_includes = ();
@@ -2290,6 +2304,27 @@ sub process {
}
}
+# typecasts on min/max could be min_t/max_t
+ if ($line =~ /^\+(?:.*?)\b(min|max)\s*\($Typecast{0,1}($LvalOrFunc)\s*,\s*$Typecast{0,1}($LvalOrFunc)\s*\)/) {
+ if (defined $2 || defined $8) {
+ my $call = $1;
+ my $cast1 = deparenthesize($2);
+ my $arg1 = $3;
+ my $cast2 = deparenthesize($8);
+ my $arg2 = $9;
+ my $cast;
+
+ if ($cast1 ne "" && $cast2 ne "") {
+ $cast = "$cast1 or $cast2";
+ } elsif ($cast1 ne "") {
+ $cast = $cast1;
+ } else {
+ $cast = $cast2;
+ }
+ WARN("$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . $herecurr);
+ }
+ }
+
# Need a space before open parenthesis after if, while etc
if ($line=~/\b(if|while|for|switch)\(/) {
ERROR("space required before the open parenthesis '('\n" . $herecurr);