Merge branch 'x86-vdso-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / scripts / checkpatch.pl
index 34eb216..010b18e 100755 (executable)
@@ -24,6 +24,7 @@ my $emacs = 0;
 my $terse = 0;
 my $file = 0;
 my $check = 0;
+my $check_orig = 0;
 my $summary = 1;
 my $mailback = 0;
 my $summary_file = 0;
@@ -146,6 +147,7 @@ GetOptions(
 help(0) if ($help);
 
 $fix = 1 if ($fix_inplace);
+$check_orig = $check;
 
 my $exit = 0;
 
@@ -397,6 +399,11 @@ foreach my $entry (@mode_permission_funcs) {
        $mode_perms_search .= $entry->[0];
 }
 
+our $declaration_macros = qr{(?x:
+       (?:$Storage\s+)?(?:DECLARE|DEFINE)_[A-Z]+\s*\(|
+       (?:$Storage\s+)?LIST_HEAD\s*\(
+)};
+
 our $allowed_asm_includes = qr{(?x:
        irq|
        memory
@@ -1808,11 +1815,13 @@ sub process {
                $here = "#$linenr: " if (!$file);
                $here = "#$realline: " if ($file);
 
+               my $found_file = 0;
                # extract the filename as it passes
                if ($line =~ /^diff --git.*?(\S+)$/) {
                        $realfile = $1;
                        $realfile =~ s@^([^/]*)/@@ if (!$file);
                        $in_commit_log = 0;
+                       $found_file = 1;
                } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
                        $realfile = $1;
                        $realfile =~ s@^([^/]*)/@@ if (!$file);
@@ -1829,6 +1838,15 @@ sub process {
                                ERROR("MODIFIED_INCLUDE_ASM",
                                      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
                        }
+                       $found_file = 1;
+               }
+
+               if ($found_file) {
+                       if ($realfile =~ m@^(drivers/net/|net/)@) {
+                               $check = 1;
+                       } else {
+                               $check = $check_orig;
+                       }
                        next;
                }
 
@@ -1926,6 +1944,12 @@ sub process {
                        }
                }
 
+# Check for old stable address
+               if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
+                       ERROR("STABLE_ADDRESS",
+                             "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
+               }
+
 # Check for unwanted Gerrit info
                if ($in_commit_log && $line =~ /^\s*change-id:/i) {
                        ERROR("GERRIT_CHANGE_ID",
@@ -2093,8 +2117,10 @@ sub process {
 
                        foreach my $compat (@compats) {
                                my $compat2 = $compat;
-                               $compat2 =~ s/\,[a-z]*\-/\,<\.\*>\-/;
-                               `grep -Erq "$compat|$compat2" $dt_path`;
+                               $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
+                               my $compat3 = $compat;
+                               $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
+                               `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
                                if ( $? >> 8 ) {
                                        WARN("UNDOCUMENTED_DT_STRING",
                                             "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
@@ -2266,18 +2292,37 @@ sub process {
                }
 
 # check for missing blank lines after declarations
-               if ($realfile =~ m@^(drivers/net/|net/)@ &&
-                   $prevline =~ /^\+\s+$Declare\s+$Ident/ &&
-                   !($prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
-                     $prevline =~ /(?:\{\s*|\\)$/) &&          #extended lines
-                   $sline =~ /^\+\s+/ &&                       #Not at char 1
-                   !($sline =~ /^\+\s+$Declare/ ||
-                     $sline =~ /^\+\s+$Ident\s+$Ident/ ||      #eg: typedef foo
+               if ($sline =~ /^\+\s+\S/ &&                     #Not at char 1
+                       # actual declarations
+                   ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
+                       # foo bar; where foo is some local typedef or #define
+                    $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
+                       # known declaration macros
+                    $prevline =~ /^\+\s+$declaration_macros/) &&
+                       # for "else if" which can look like "$Ident $Ident"
+                   !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
+                       # other possible extensions of declaration lines
+                     $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
+                       # not starting a section or a macro "\" extended line
+                     $prevline =~ /(?:\{\s*|\\)$/) &&
+                       # looks like a declaration
+                   !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
+                       # foo bar; where foo is some local typedef or #define
+                     $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
+                       # known declaration macros
+                     $sline =~ /^\+\s+$declaration_macros/ ||
+                       # start of struct or union or enum
                      $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
-                     $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(])/ ||
-                     $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
+                       # start or end of block or continuation of declaration
+                     $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
+                       # bitfield continuation
+                     $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
+                       # other possible extensions of declaration lines
+                     $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
+                       # indentation of previous and current line are the same
+                   (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
                        WARN("SPACING",
-                            "networking uses a blank line after declarations\n" . $hereprev);
+                            "Missing a blank line after declarations\n" . $hereprev);
                }
 
 # check for spaces at the beginning of a line.
@@ -3431,6 +3476,13 @@ sub process {
                        }
                }
 
+# unnecessary return in a void function? (a single leading tab, then return;)
+               if ($sline =~ /^\+\treturn\s*;\s*$/ &&
+                   $prevline =~ /^\+/) {
+                       WARN("RETURN_VOID",
+                            "void function return statements are not generally useful\n" . $herecurr);
+               }
+
 # if statements using unnecessary parentheses - ie: if ((foo == bar))
                if ($^V && $^V ge 5.10.0 &&
                    $line =~ /\bif\s*((?:\(\s*){2,})/) {
@@ -3782,6 +3834,17 @@ sub process {
                                        WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
                                             "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
                                }
+                       } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
+                               $ctx =~ s/\n*$//;
+                               my $cnt = statement_rawlines($ctx);
+                               my $herectx = $here . "\n";
+
+                               for (my $n = 0; $n < $cnt; $n++) {
+                                       $herectx .= raw_line($linenr, $n) . "\n";
+                               }
+
+                               WARN("TRAILING_SEMICOLON",
+                                    "macros should not use a trailing semicolon\n" . "$herectx");
                        }
                }
 
@@ -4264,6 +4327,27 @@ sub process {
                             "unchecked sscanf return value\n" . "$here\n$stat_real\n");
                }
 
+# check for simple sscanf that should be kstrto<foo>
+               if ($^V && $^V ge 5.10.0 &&
+                   defined $stat &&
+                   $line =~ /\bsscanf\b/) {
+                       my $lc = $stat =~ tr@\n@@;
+                       $lc = $lc + $linenr;
+                       my $stat_real = raw_line($linenr, 0);
+                       for (my $count = $linenr + 1; $count <= $lc; $count++) {
+                               $stat_real = $stat_real . "\n" . raw_line($count, 0);
+                       }
+                       if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
+                               my $format = $6;
+                               my $count = $format =~ tr@%@%@;
+                               if ($count == 1 &&
+                                   $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
+                                       WARN("SSCANF_TO_KSTRTO",
+                                            "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
+                               }
+                       }
+               }
+
 # check for new externs in .h files.
                if ($realfile =~ /\.h$/ &&
                    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
@@ -4328,6 +4412,30 @@ sub process {
                            "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
                }
 
+# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
+               if ($^V && $^V ge 5.10.0 &&
+                   $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/) {
+                       my $oldfunc = $3;
+                       my $a1 = $4;
+                       my $a2 = $10;
+                       my $newfunc = "kmalloc_array";
+                       $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
+                       if ($a1 =~ /^sizeof\s*\S/ || $a2 =~ /^sizeof\s*\S/) {
+                               if (WARN("ALLOC_WITH_MULTIPLY",
+                                        "Prefer $newfunc over $oldfunc with multiply\n" . $herecurr) &&
+                                   $fix) {
+                                       my $r1 = $a1;
+                                       my $r2 = $a2;
+                                       if ($a1 =~ /^sizeof\s*\S/) {
+                                               $r1 = $a2;
+                                               $r2 = $a1;
+                                       }
+                                       $fixed[$linenr - 1] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
+
+                               }
+                       }
+               }
+
 # check for krealloc arg reuse
                if ($^V && $^V ge 5.10.0 &&
                    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
@@ -4443,10 +4551,10 @@ sub process {
                             "$1 is obsolete, use k$3 instead\n" . $herecurr);
                }
 
-# check for __initcall(), use device_initcall() explicitly please
+# check for __initcall(), use device_initcall() explicitly or more appropriate function please
                if ($line =~ /^.\s*__initcall\s*\(/) {
                        WARN("USE_DEVICE_INITCALL",
-                            "please use device_initcall() instead of __initcall()\n" . $herecurr);
+                            "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
                }
 
 # check for various ops structs, ensure they are const.