hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/scripts/checkpatch.pl
....@@ -43,6 +43,8 @@
4343 my $fix = 0;
4444 my $fix_inplace = 0;
4545 my $root;
46
+my $gitroot = $ENV{'GIT_DIR'};
47
+$gitroot = ".git" if !defined($gitroot);
4648 my %debug;
4749 my %camelcase = ();
4850 my %use_type = ();
....@@ -51,7 +53,7 @@
5153 my @ignore = ();
5254 my $help = 0;
5355 my $configuration_file = ".checkpatch.conf";
54
-my $max_line_length = 80;
56
+my $max_line_length = 100;
5557 my $ignore_perl_version = 0;
5658 my $minimum_perl_version = 5.10.0;
5759 my $min_conf_desc_length = 4;
....@@ -59,9 +61,13 @@
5961 my $codespell = 0;
6062 my $codespellfile = "/usr/share/codespell/dictionary.txt";
6163 my $conststructsfile = "$D/const_structs.checkpatch";
62
-my $typedefsfile = "";
64
+my $typedefsfile;
6365 my $color = "auto";
64
-my $allow_c99_comments = 1;
66
+my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
67
+# git output parsing needs US English output, so first set backtick child process LANGUAGE
68
+my $git_command ='export LANGUAGE=en_US.UTF-8; git';
69
+my $tabsize = 8;
70
+my ${CONFIG_} = "CONFIG_";
6571
6672 sub help {
6773 my ($exitcode) = @_;
....@@ -94,8 +100,11 @@
94100 --types TYPE(,TYPE2...) show only these comma separated message types
95101 --ignore TYPE(,TYPE2...) ignore various comma separated message types
96102 --show-types show the specific message type in the output
97
- --max-line-length=n set the maximum line length, if exceeded, warn
103
+ --max-line-length=n set the maximum line length, (default $max_line_length)
104
+ if exceeded, warn on patches
105
+ requires --strict for use with --file
98106 --min-conf-desc-length=n set the min description length, if shorter, warn
107
+ --tab-size=n set the number of spaces for tab (default $tabsize)
99108 --root=PATH PATH to the kernel tree root
100109 --no-summary suppress the per-file summary
101110 --mailback only produce a report in case of warnings/errors
....@@ -121,6 +130,8 @@
121130 --typedefsfile Read additional types from this file
122131 --color[=WHEN] Use colors 'always', 'never', or only when output
123132 is a terminal ('auto'). Default is 'auto'.
133
+ --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default
134
+ ${CONFIG_})
124135 -h, --help, --version display this help and exit
125136
126137 When FILE is - read standard input.
....@@ -213,6 +224,7 @@
213224 'list-types!' => \$list_types,
214225 'max-line-length=i' => \$max_line_length,
215226 'min-conf-desc-length=i' => \$min_conf_desc_length,
227
+ 'tab-size=i' => \$tabsize,
216228 'root=s' => \$root,
217229 'summary!' => \$summary,
218230 'mailback!' => \$mailback,
....@@ -228,6 +240,7 @@
228240 'color=s' => \$color,
229241 'no-color' => \$color, #keep old behaviors of -nocolor
230242 'nocolor' => \$color, #keep old behaviors of -nocolor
243
+ 'kconfig-prefix=s' => \${CONFIG_},
231244 'h|help' => \$help,
232245 'version' => \$help
233246 ) or help(1);
....@@ -238,6 +251,8 @@
238251
239252 $fix = 1 if ($fix_inplace);
240253 $check_orig = $check;
254
+
255
+die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
241256
242257 my $exit = 0;
243258
....@@ -262,8 +277,11 @@
262277 } elsif ($color =~ /^auto$/i) {
263278 $color = (-t STDOUT);
264279 } else {
265
- die "Invalid color mode: $color\n";
280
+ die "$P: Invalid color mode: $color\n";
266281 }
282
+
283
+# skip TAB size 1 to avoid additional checks on $tabsize - 1
284
+die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
267285
268286 sub hash_save_array_words {
269287 my ($hashRef, $arrayRef) = @_;
....@@ -466,8 +484,19 @@
466484 seq_vprintf|seq_printf|seq_puts
467485 )};
468486
487
+our $allocFunctions = qr{(?x:
488
+ (?:(?:devm_)?
489
+ (?:kv|k|v)[czm]alloc(?:_node|_array)? |
490
+ kstrdup(?:_const)? |
491
+ kmemdup(?:_nul)?) |
492
+ (?:\w+)?alloc_skb(?:_ip_align)? |
493
+ # dev_alloc_skb/netdev_alloc_skb, et al
494
+ dma_alloc_coherent
495
+)};
496
+
469497 our $signature_tags = qr{(?xi:
470498 Signed-off-by:|
499
+ Co-developed-by:|
471500 Acked-by:|
472501 Tested-by:|
473502 Reviewed-by:|
....@@ -565,6 +594,8 @@
565594 ["__ATTR", 2],
566595 );
567596
597
+my $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
598
+
568599 #Create a search pattern for all these functions to speed up a loop below
569600 our $mode_perms_search = "";
570601 foreach my $entry (@mode_permission_funcs) {
....@@ -572,6 +603,27 @@
572603 $mode_perms_search .= $entry->[0];
573604 }
574605 $mode_perms_search = "(?:${mode_perms_search})";
606
+
607
+our %deprecated_apis = (
608
+ "synchronize_rcu_bh" => "synchronize_rcu",
609
+ "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited",
610
+ "call_rcu_bh" => "call_rcu",
611
+ "rcu_barrier_bh" => "rcu_barrier",
612
+ "synchronize_sched" => "synchronize_rcu",
613
+ "synchronize_sched_expedited" => "synchronize_rcu_expedited",
614
+ "call_rcu_sched" => "call_rcu",
615
+ "rcu_barrier_sched" => "rcu_barrier",
616
+ "get_state_synchronize_sched" => "get_state_synchronize_rcu",
617
+ "cond_synchronize_sched" => "cond_synchronize_rcu",
618
+);
619
+
620
+#Create a search pattern for all these strings to speed up a loop below
621
+our $deprecated_apis_search = "";
622
+foreach my $entry (keys %deprecated_apis) {
623
+ $deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
624
+ $deprecated_apis_search .= $entry;
625
+}
626
+$deprecated_apis_search = "(?:${deprecated_apis_search})";
575627
576628 our $mode_perms_world_writable = qr{
577629 S_IWUGO |
....@@ -712,7 +764,7 @@
712764 next;
713765 }
714766
715
- $$wordsRef .= '|' if ($$wordsRef ne "");
767
+ $$wordsRef .= '|' if (defined $$wordsRef);
716768 $$wordsRef .= $line;
717769 }
718770 close($file);
....@@ -722,16 +774,18 @@
722774 return 0;
723775 }
724776
725
-my $const_structs = "";
726
-read_words(\$const_structs, $conststructsfile)
727
- or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
777
+my $const_structs;
778
+if (show_type("CONST_STRUCT")) {
779
+ read_words(\$const_structs, $conststructsfile)
780
+ or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
781
+}
728782
729
-my $typeOtherTypedefs = "";
730
-if (length($typedefsfile)) {
783
+if (defined($typedefsfile)) {
784
+ my $typeOtherTypedefs;
731785 read_words(\$typeOtherTypedefs, $typedefsfile)
732786 or warn "No additional types will be considered - file '$typedefsfile': $!\n";
787
+ $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
733788 }
734
-$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
735789
736790 sub build_types {
737791 my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
....@@ -770,12 +824,12 @@
770824 }x;
771825 $Type = qr{
772826 $NonptrType
773
- (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
827
+ (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
774828 (?:\s+$Inline|\s+$Modifier)*
775829 }x;
776830 $TypeMisordered = qr{
777831 $NonptrTypeMisordered
778
- (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
832
+ (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
779833 (?:\s+$Inline|\s+$Modifier)*
780834 }x;
781835 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
....@@ -796,7 +850,6 @@
796850 our $declaration_macros = qr{(?x:
797851 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
798852 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
799
- (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
800853 (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
801854 )};
802855
....@@ -840,20 +893,24 @@
840893 }
841894 }
842895
896
+our %maintained_status = ();
897
+
843898 sub is_maintained_obsolete {
844899 my ($filename) = @_;
845900
846901 return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
847902
848
- my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
903
+ if (!exists($maintained_status{$filename})) {
904
+ $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
905
+ }
849906
850
- return $status =~ /obsolete/i;
907
+ return $maintained_status{$filename} =~ /obsolete/i;
851908 }
852909
853910 sub is_SPDX_License_valid {
854911 my ($license) = @_;
855912
856
- return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
913
+ return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
857914
858915 my $root_path = abs_path($root);
859916 my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
....@@ -871,8 +928,8 @@
871928
872929 $camelcase_seeded = 1;
873930
874
- if (-e ".git") {
875
- my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
931
+ if (-e "$gitroot") {
932
+ my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
876933 chomp $git_last_include_commit;
877934 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
878935 } else {
....@@ -899,8 +956,8 @@
899956 return;
900957 }
901958
902
- if (-e ".git") {
903
- $files = `git ls-files "include/*.h"`;
959
+ if (-e "$gitroot") {
960
+ $files = `${git_command} ls-files "include/*.h"`;
904961 @include_files = split('\n', $files);
905962 }
906963
....@@ -919,18 +976,28 @@
919976 }
920977 }
921978
979
+sub git_is_single_file {
980
+ my ($filename) = @_;
981
+
982
+ return 0 if ((which("git") eq "") || !(-e "$gitroot"));
983
+
984
+ my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
985
+ my $count = $output =~ tr/\n//;
986
+ return $count eq 1 && $output =~ m{^${filename}$};
987
+}
988
+
922989 sub git_commit_info {
923990 my ($commit, $id, $desc) = @_;
924991
925
- return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
992
+ return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
926993
927
- my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
994
+ my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
928995 $output =~ s/^\s*//gm;
929996 my @lines = split("\n", $output);
930997
931998 return ($id, $desc) if ($#lines < 0);
932999
933
- if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
1000
+ if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
9341001 # Maybe one day convert this block of bash into something that returns
9351002 # all matching commit ids, but it's very slow...
9361003 #
....@@ -961,7 +1028,7 @@
9611028
9621029 # If input is git commits, extract all commits from the commit expressions.
9631030 # For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
964
-die "$P: No git repository found\n" if ($git && !-e ".git");
1031
+die "$P: No git repository found\n" if ($git && !-e "$gitroot");
9651032
9661033 if ($git) {
9671034 my @commits = ();
....@@ -974,7 +1041,7 @@
9741041 } else {
9751042 $git_range = "-1 $commit_expr";
9761043 }
977
- my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
1044
+ my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
9781045 foreach my $line (split(/\n/, $lines)) {
9791046 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
9801047 next if (!defined($1) || !defined($2));
....@@ -989,8 +1056,12 @@
9891056 }
9901057
9911058 my $vname;
1059
+$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
9921060 for my $filename (@ARGV) {
9931061 my $FILE;
1062
+ my $is_git_file = git_is_single_file($filename);
1063
+ my $oldfile = $file;
1064
+ $file = 1 if ($is_git_file);
9941065 if ($git) {
9951066 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
9961067 die "$P: $filename: git format-patch failed - $!\n";
....@@ -1013,6 +1084,7 @@
10131084 while (<$FILE>) {
10141085 chomp;
10151086 push(@rawlines, $_);
1087
+ $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
10161088 }
10171089 close($FILE);
10181090
....@@ -1034,6 +1106,7 @@
10341106 @modifierListFile = ();
10351107 @typeListFile = ();
10361108 build_types();
1109
+ $file = $oldfile if ($is_git_file);
10371110 }
10381111
10391112 if (!$quiet) {
....@@ -1079,6 +1152,7 @@
10791152 my ($formatted_email) = @_;
10801153
10811154 my $name = "";
1155
+ my $name_comment = "";
10821156 my $address = "";
10831157 my $comment = "";
10841158
....@@ -1109,8 +1183,12 @@
11091183 }
11101184 }
11111185
1186
+ $comment = trim($comment);
11121187 $name = trim($name);
11131188 $name =~ s/^\"|\"$//g;
1189
+ if ($name =~ s/(\s*\([^\)]+\))\s*//) {
1190
+ $name_comment = trim($1);
1191
+ }
11141192 $address = trim($address);
11151193 $address =~ s/^\<|\>$//g;
11161194
....@@ -1119,14 +1197,16 @@
11191197 $name = "\"$name\"";
11201198 }
11211199
1122
- return ($name, $address, $comment);
1200
+ return ($name, $name_comment, $address, $comment);
11231201 }
11241202
11251203 sub format_email {
1126
- my ($name, $address) = @_;
1204
+ my ($name, $name_comment, $address, $comment) = @_;
11271205
11281206 my $formatted_email;
11291207
1208
+ $name_comment = trim($name_comment);
1209
+ $comment = trim($comment);
11301210 $name = trim($name);
11311211 $name =~ s/^\"|\"$//g;
11321212 $address = trim($address);
....@@ -1139,10 +1219,33 @@
11391219 if ("$name" eq "") {
11401220 $formatted_email = "$address";
11411221 } else {
1142
- $formatted_email = "$name <$address>";
1222
+ $formatted_email = "$name$name_comment <$address>";
11431223 }
1144
-
1224
+ $formatted_email .= "$comment";
11451225 return $formatted_email;
1226
+}
1227
+
1228
+sub reformat_email {
1229
+ my ($email) = @_;
1230
+
1231
+ my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
1232
+ return format_email($email_name, $name_comment, $email_address, $comment);
1233
+}
1234
+
1235
+sub same_email_addresses {
1236
+ my ($email1, $email2, $match_comment) = @_;
1237
+
1238
+ my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1239
+ my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1240
+
1241
+ if ($match_comment != 1) {
1242
+ return $email1_name eq $email2_name &&
1243
+ $email1_address eq $email2_address;
1244
+ }
1245
+ return $email1_name eq $email2_name &&
1246
+ $email1_address eq $email2_address &&
1247
+ $name1_comment eq $name2_comment &&
1248
+ $comment1 eq $comment2;
11461249 }
11471250
11481251 sub which {
....@@ -1178,7 +1281,7 @@
11781281 if ($c eq "\t") {
11791282 $res .= ' ';
11801283 $n++;
1181
- for (; ($n % 8) != 0; $n++) {
1284
+ for (; ($n % $tabsize) != 0; $n++) {
11821285 $res .= ' ';
11831286 }
11841287 next;
....@@ -1607,8 +1710,16 @@
16071710 sub ctx_locate_comment {
16081711 my ($first_line, $end_line) = @_;
16091712
1713
+ # If c99 comment on the current line, or the line before or after
1714
+ my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1715
+ return $current_comment if (defined $current_comment);
1716
+ ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1717
+ return $current_comment if (defined $current_comment);
1718
+ ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1719
+ return $current_comment if (defined $current_comment);
1720
+
16101721 # Catch a comment on the end of the line itself.
1611
- my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1722
+ ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
16121723 return $current_comment if (defined $current_comment);
16131724
16141725 # Look through the context and try and figure out if there is a
....@@ -2191,7 +2302,7 @@
21912302 sub tabify {
21922303 my ($leading) = @_;
21932304
2194
- my $source_indent = 8;
2305
+ my $source_indent = $tabsize;
21952306 my $max_spaces_before_tab = $source_indent - 1;
21962307 my $spaces_to_tab = " " x $source_indent;
21972308
....@@ -2233,6 +2344,19 @@
22332344 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
22342345 }
22352346
2347
+sub get_raw_comment {
2348
+ my ($line, $rawline) = @_;
2349
+ my $comment = '';
2350
+
2351
+ for my $i (0 .. (length($line) - 1)) {
2352
+ if (substr($line, $i, 1) eq "$;") {
2353
+ $comment .= substr($rawline, $i, 1);
2354
+ }
2355
+ }
2356
+
2357
+ return $comment;
2358
+}
2359
+
22362360 sub process {
22372361 my $filename = shift;
22382362
....@@ -2251,10 +2375,12 @@
22512375 my $signoff = 0;
22522376 my $author = '';
22532377 my $authorsignoff = 0;
2378
+ my $author_sob = '';
22542379 my $is_patch = 0;
22552380 my $is_binding_patch = -1;
22562381 my $in_header_lines = $file ? 0 : 1;
22572382 my $in_commit_log = 0; #Scanning lines before patch
2383
+ my $has_patch_separator = 0; #Found a --- line
22582384 my $has_commit_log = 0; #Encountered lines before patch
22592385 my $commit_log_lines = 0; #Number of commit log lines
22602386 my $commit_log_possible_stack_dump = 0;
....@@ -2313,7 +2439,7 @@
23132439
23142440 if ($rawline=~/^\+\+\+\s+(\S+)/) {
23152441 $setup_docs = 0;
2316
- if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2442
+ if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
23172443 $setup_docs = 1;
23182444 }
23192445 #next;
....@@ -2394,6 +2520,7 @@
23942520 $sline =~ s/$;/ /g; #with comments as spaces
23952521
23962522 my $rawline = $rawlines[$linenr - 1];
2523
+ my $raw_comment = get_raw_comment($line, $rawline);
23972524
23982525 # check if it's a mode change, rename or start of a patch
23992526 if (!$in_commit_log &&
....@@ -2512,7 +2639,7 @@
25122639 if (($last_binding_patch != -1) &&
25132640 ($last_binding_patch ^ $is_binding_patch)) {
25142641 WARN("DT_SPLIT_BINDING_PATCH",
2515
- "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
2642
+ "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
25162643 }
25172644 }
25182645
....@@ -2563,21 +2690,58 @@
25632690 # Check the patch for a From:
25642691 if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
25652692 $author = $1;
2693
+ my $curline = $linenr;
2694
+ while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2695
+ $author .= $1;
2696
+ }
25662697 $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
25672698 $author =~ s/"//g;
2699
+ $author = reformat_email($author);
25682700 }
25692701
25702702 # Check the patch for a signoff:
2571
- if ($line =~ /^\s*signed-off-by:/i) {
2703
+ if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
25722704 $signoff++;
25732705 $in_commit_log = 0;
2574
- if ($author ne '') {
2575
- my $l = $line;
2576
- $l =~ s/"//g;
2577
- if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
2578
- $authorsignoff = 1;
2706
+ if ($author ne '' && $authorsignoff != 1) {
2707
+ if (same_email_addresses($1, $author, 1)) {
2708
+ $authorsignoff = 1;
2709
+ } else {
2710
+ my $ctx = $1;
2711
+ my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
2712
+ my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
2713
+
2714
+ if ($email_address eq $author_address && $email_name eq $author_name) {
2715
+ $author_sob = $ctx;
2716
+ $authorsignoff = 2;
2717
+ } elsif ($email_address eq $author_address) {
2718
+ $author_sob = $ctx;
2719
+ $authorsignoff = 3;
2720
+ } elsif ($email_name eq $author_name) {
2721
+ $author_sob = $ctx;
2722
+ $authorsignoff = 4;
2723
+
2724
+ my $address1 = $email_address;
2725
+ my $address2 = $author_address;
2726
+
2727
+ if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
2728
+ $address1 = "$1$2";
2729
+ }
2730
+ if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
2731
+ $address2 = "$1$2";
2732
+ }
2733
+ if ($address1 eq $address2) {
2734
+ $authorsignoff = 5;
2735
+ }
2736
+ }
25792737 }
25802738 }
2739
+ }
2740
+
2741
+# Check for patch separator
2742
+ if ($line =~ /^---$/) {
2743
+ $has_patch_separator = 1;
2744
+ $in_commit_log = 0;
25812745 }
25822746
25832747 # Check if MAINTAINERS is being updated. If so, there's probably no need to
....@@ -2625,8 +2789,8 @@
26252789 }
26262790 }
26272791
2628
- my ($email_name, $email_address, $comment) = parse_email($email);
2629
- my $suggested_email = format_email(($email_name, $email_address));
2792
+ my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
2793
+ my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
26302794 if ($suggested_email eq "") {
26312795 ERROR("BAD_SIGN_OFF",
26322796 "Unrecognized email address: '$email'\n" . $herecurr);
....@@ -2636,11 +2800,9 @@
26362800 $dequoted =~ s/" </ </;
26372801 # Don't force email to have quotes
26382802 # Allow just an angle bracketed address
2639
- if ("$dequoted$comment" ne $email &&
2640
- "<$email_address>$comment" ne $email &&
2641
- "$suggested_email$comment" ne $email) {
2803
+ if (!same_email_addresses($email, $suggested_email, 0)) {
26422804 WARN("BAD_SIGN_OFF",
2643
- "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
2805
+ "email address '$email' might be better as '$suggested_email'\n" . $herecurr);
26442806 }
26452807 }
26462808
....@@ -2654,6 +2816,24 @@
26542816 } else {
26552817 $signatures{$sig_nospace} = 1;
26562818 }
2819
+
2820
+# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
2821
+ if ($sign_off =~ /^co-developed-by:$/i) {
2822
+ if ($email eq $author) {
2823
+ WARN("BAD_SIGN_OFF",
2824
+ "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
2825
+ }
2826
+ if (!defined $lines[$linenr]) {
2827
+ WARN("BAD_SIGN_OFF",
2828
+ "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
2829
+ } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
2830
+ WARN("BAD_SIGN_OFF",
2831
+ "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2832
+ } elsif ($1 ne $email) {
2833
+ WARN("BAD_SIGN_OFF",
2834
+ "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
2835
+ }
2836
+ }
26572837 }
26582838
26592839 # Check email subject for common tools that don't need to be mentioned
....@@ -2663,10 +2843,10 @@
26632843 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
26642844 }
26652845
2666
-# Check for unwanted Gerrit info
2667
- if ($in_commit_log && $line =~ /^\s*change-id:/i) {
2846
+# Check for Gerrit Change-Ids not in any patch context
2847
+ if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
26682848 ERROR("GERRIT_CHANGE_ID",
2669
- "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
2849
+ "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
26702850 }
26712851
26722852 # Check if the commit log is in a possible stack dump
....@@ -2674,8 +2854,10 @@
26742854 ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
26752855 $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
26762856 # timestamp
2677
- $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2678
- # stack dump address
2857
+ $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
2858
+ $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
2859
+ $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
2860
+ # stack dump address styles
26792861 $commit_log_possible_stack_dump = 1;
26802862 }
26812863
....@@ -2702,7 +2884,7 @@
27022884
27032885 # Check for git id commit length and improperly formed commit descriptions
27042886 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2705
- $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
2887
+ $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
27062888 $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
27072889 ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
27082890 ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
....@@ -2769,6 +2951,14 @@
27692951 $reported_maintainer_file = 1;
27702952 WARN("FILE_PATH_CHANGES",
27712953 "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
2954
+ }
2955
+
2956
+# Check for adding new DT bindings not in schema format
2957
+ if (!$in_commit_log &&
2958
+ ($line =~ /^new file mode\s*\d+\s*$/) &&
2959
+ ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
2960
+ WARN("DT_SCHEMA_BINDING_PATCH",
2961
+ "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
27722962 }
27732963
27742964 # Check for wrappage within a valid hunk of the file
....@@ -2847,6 +3037,53 @@
28473037 }
28483038 }
28493039
3040
+# check for invalid commit id
3041
+ if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3042
+ my $id;
3043
+ my $description;
3044
+ ($id, $description) = git_commit_info($2, undef, undef);
3045
+ if (!defined($id)) {
3046
+ WARN("UNKNOWN_COMMIT_ID",
3047
+ "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3048
+ }
3049
+ }
3050
+
3051
+# check for repeated words separated by a single space
3052
+ if ($rawline =~ /^\+/ || $in_commit_log) {
3053
+ while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3054
+
3055
+ my $first = $1;
3056
+ my $second = $2;
3057
+
3058
+ if ($first =~ /(?:struct|union|enum)/) {
3059
+ pos($rawline) += length($first) + length($second) + 1;
3060
+ next;
3061
+ }
3062
+
3063
+ next if ($first ne $second);
3064
+ next if ($first eq 'long');
3065
+
3066
+ if (WARN("REPEATED_WORD",
3067
+ "Possible repeated word: '$first'\n" . $herecurr) &&
3068
+ $fix) {
3069
+ $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3070
+ }
3071
+ }
3072
+
3073
+ # if it's a repeated word on consecutive lines in a comment block
3074
+ if ($prevline =~ /$;+\s*$/ &&
3075
+ $prevrawline =~ /($word_pattern)\s*$/) {
3076
+ my $last_word = $1;
3077
+ if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3078
+ if (WARN("REPEATED_WORD",
3079
+ "Possible repeated word: '$last_word'\n" . $hereprev) &&
3080
+ $fix) {
3081
+ $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3082
+ }
3083
+ }
3084
+ }
3085
+ }
3086
+
28503087 # ignore non-hunk lines and lines being removed
28513088 next if (!$hunk_line || $line =~ /^-/);
28523089
....@@ -2905,11 +3142,7 @@
29053142
29063143 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
29073144 $is_start = 1;
2908
- } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
2909
- if ($lines[$ln - 1] =~ "---help---") {
2910
- WARN("CONFIG_DESCRIPTION",
2911
- "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
2912
- }
3145
+ } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
29133146 $length = -1;
29143147 }
29153148
....@@ -2936,14 +3169,43 @@
29363169 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
29373170 }
29383171
2939
-# check for MAINTAINERS entries that don't have the right form
2940
- if ($realfile =~ /^MAINTAINERS$/ &&
2941
- $rawline =~ /^\+[A-Z]:/ &&
2942
- $rawline !~ /^\+[A-Z]:\t\S/) {
2943
- if (WARN("MAINTAINERS_STYLE",
2944
- "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
2945
- $fix) {
2946
- $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3172
+# check MAINTAINERS entries
3173
+ if ($realfile =~ /^MAINTAINERS$/) {
3174
+# check MAINTAINERS entries for the right form
3175
+ if ($rawline =~ /^\+[A-Z]:/ &&
3176
+ $rawline !~ /^\+[A-Z]:\t\S/) {
3177
+ if (WARN("MAINTAINERS_STYLE",
3178
+ "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3179
+ $fix) {
3180
+ $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3181
+ }
3182
+ }
3183
+# check MAINTAINERS entries for the right ordering too
3184
+ my $preferred_order = 'MRLSWQBCPTFXNK';
3185
+ if ($rawline =~ /^\+[A-Z]:/ &&
3186
+ $prevrawline =~ /^[\+ ][A-Z]:/) {
3187
+ $rawline =~ /^\+([A-Z]):\s*(.*)/;
3188
+ my $cur = $1;
3189
+ my $curval = $2;
3190
+ $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
3191
+ my $prev = $1;
3192
+ my $prevval = $2;
3193
+ my $curindex = index($preferred_order, $cur);
3194
+ my $previndex = index($preferred_order, $prev);
3195
+ if ($curindex < 0) {
3196
+ WARN("MAINTAINERS_STYLE",
3197
+ "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
3198
+ } else {
3199
+ if ($previndex >= 0 && $curindex < $previndex) {
3200
+ WARN("MAINTAINERS_STYLE",
3201
+ "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
3202
+ } elsif ((($prev eq 'F' && $cur eq 'F') ||
3203
+ ($prev eq 'X' && $cur eq 'X')) &&
3204
+ ($prevval cmp $curval) > 0) {
3205
+ WARN("MAINTAINERS_STYLE",
3206
+ "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
3207
+ }
3208
+ }
29473209 }
29483210 }
29493211
....@@ -2976,7 +3238,7 @@
29763238 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
29773239
29783240 my $dt_path = $root . "/Documentation/devicetree/bindings/";
2979
- my $vp_file = $dt_path . "vendor-prefixes.txt";
3241
+ my $vp_file = $dt_path . "vendor-prefixes.yaml";
29803242
29813243 foreach my $compat (@compats) {
29823244 my $compat2 = $compat;
....@@ -2991,7 +3253,7 @@
29913253
29923254 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
29933255 my $vendor = $1;
2994
- `grep -Eq "^$vendor\\b" $vp_file`;
3256
+ `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
29953257 if ( $? >> 8 ) {
29963258 WARN("UNDOCUMENTED_DT_STRING",
29973259 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
....@@ -3009,28 +3271,61 @@
30093271 $comment = '/*';
30103272 } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
30113273 $comment = '//';
3012
- } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
3274
+ } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
30133275 $comment = '#';
30143276 } elsif ($realfile =~ /\.rst$/) {
30153277 $comment = '..';
30163278 }
30173279
3280
+# check SPDX comment style for .[chsS] files
3281
+ if ($realfile =~ /\.[chsS]$/ &&
3282
+ $rawline =~ /SPDX-License-Identifier:/ &&
3283
+ $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3284
+ WARN("SPDX_LICENSE_TAG",
3285
+ "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3286
+ }
3287
+
30183288 if ($comment !~ /^$/ &&
3019
- $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) {
3020
- WARN("SPDX_LICENSE_TAG",
3021
- "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
3289
+ $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
3290
+ WARN("SPDX_LICENSE_TAG",
3291
+ "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
30223292 } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
3023
- my $spdx_license = $1;
3024
- if (!is_SPDX_License_valid($spdx_license)) {
3025
- WARN("SPDX_LICENSE_TAG",
3026
- "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3027
- }
3293
+ my $spdx_license = $1;
3294
+ if (!is_SPDX_License_valid($spdx_license)) {
3295
+ WARN("SPDX_LICENSE_TAG",
3296
+ "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3297
+ }
3298
+ if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
3299
+ not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
3300
+ my $msg_level = \&WARN;
3301
+ $msg_level = \&CHK if ($file);
3302
+ if (&{$msg_level}("SPDX_LICENSE_TAG",
3303
+
3304
+ "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
3305
+ $fix) {
3306
+ $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
3307
+ }
3308
+ }
30283309 }
30293310 }
30303311 }
30313312
3313
+# check for embedded filenames
3314
+ if ($rawline =~ /^\+.*\Q$realfile\E/) {
3315
+ WARN("EMBEDDED_FILENAME",
3316
+ "It's generally not useful to have the filename in the file\n" . $herecurr);
3317
+ }
3318
+
30323319 # check we are in a valid source file if not then ignore this hunk
30333320 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
3321
+
3322
+# check for using SPDX-License-Identifier on the wrong line number
3323
+ if ($realline != $checklicenseline &&
3324
+ $rawline =~ /\bSPDX-License-Identifier:/ &&
3325
+ substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3326
+ WARN("SPDX_LICENSE_TAG",
3327
+ "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3328
+ }
30343329
30353330 # line length limit (with some exclusions)
30363331 #
....@@ -3089,8 +3384,10 @@
30893384
30903385 if ($msg_type ne "" &&
30913386 (show_type("LONG_LINE") || show_type($msg_type))) {
3092
- WARN($msg_type,
3093
- "line over $max_line_length characters\n" . $herecurr);
3387
+ my $msg_level = \&WARN;
3388
+ $msg_level = \&CHK if ($file);
3389
+ &{$msg_level}($msg_type,
3390
+ "line length of $length exceeds $max_line_length columns\n" . $herecurr);
30943391 }
30953392 }
30963393
....@@ -3104,7 +3401,7 @@
31043401 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
31053402
31063403 # at the beginning of a line any tabs must come first and anything
3107
-# more than 8 must use tabs.
3404
+# more than $tabsize must use tabs.
31083405 if ($rawline =~ /^\+\s* \t\s*\S/ ||
31093406 $rawline =~ /^\+\s* \s*/) {
31103407 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
....@@ -3123,7 +3420,7 @@
31233420 "please, no space before tabs\n" . $herevet) &&
31243421 $fix) {
31253422 while ($fixed[$fixlinenr] =~
3126
- s/(^\+.*) {8,8}\t/$1\t\t/) {}
3423
+ s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
31273424 while ($fixed[$fixlinenr] =~
31283425 s/(^\+.*) +\t/$1\t/) {}
31293426 }
....@@ -3145,11 +3442,11 @@
31453442 if ($perl_version_ok &&
31463443 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
31473444 my $indent = length($1);
3148
- if ($indent % 8) {
3445
+ if ($indent % $tabsize) {
31493446 if (WARN("TABSTOP",
31503447 "Statements should start on a tabstop\n" . $herecurr) &&
31513448 $fix) {
3152
- $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
3449
+ $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
31533450 }
31543451 }
31553452 }
....@@ -3167,8 +3464,8 @@
31673464 my $newindent = $2;
31683465
31693466 my $goodtabindent = $oldindent .
3170
- "\t" x ($pos / 8) .
3171
- " " x ($pos % 8);
3467
+ "\t" x ($pos / $tabsize) .
3468
+ " " x ($pos % $tabsize);
31723469 my $goodspaceindent = $oldindent . " " x $pos;
31733470
31743471 if ($newindent ne $goodtabindent &&
....@@ -3206,7 +3503,7 @@
32063503 if ($realfile =~ m@^(drivers/net/|net/)@ &&
32073504 $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
32083505 $rawline =~ /^\+[ \t]*\*/ &&
3209
- $realline > 2) {
3506
+ $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
32103507 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
32113508 "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
32123509 }
....@@ -3639,11 +3936,11 @@
36393936 #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
36403937
36413938 if ($check && $s ne '' &&
3642
- (($sindent % 8) != 0 ||
3939
+ (($sindent % $tabsize) != 0 ||
36433940 ($sindent < $indent) ||
36443941 ($sindent == $indent &&
36453942 ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
3646
- ($sindent > $indent + 8))) {
3943
+ ($sindent > $indent + $tabsize))) {
36473944 WARN("SUSPECT_CODE_INDENT",
36483945 "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
36493946 }
....@@ -3664,6 +3961,17 @@
36643961
36653962 #ignore lines not being added
36663963 next if ($line =~ /^[^\+]/);
3964
+
3965
+# check for self assignments used to avoid compiler warnings
3966
+# e.g.: int foo = foo, *bar = NULL;
3967
+# struct foo bar = *(&(bar));
3968
+ if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
3969
+ my $var = $1;
3970
+ if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
3971
+ WARN("SELF_ASSIGNMENT",
3972
+ "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
3973
+ }
3974
+ }
36673975
36683976 # check for dereferences that span multiple lines
36693977 if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
....@@ -3869,14 +4177,23 @@
38694177 WARN("STATIC_CONST_CHAR_ARRAY",
38704178 "static const char * array should probably be static const char * const\n" .
38714179 $herecurr);
3872
- }
4180
+ }
4181
+
4182
+# check for initialized const char arrays that should be static const
4183
+ if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
4184
+ if (WARN("STATIC_CONST_CHAR_ARRAY",
4185
+ "const array should probably be static const\n" . $herecurr) &&
4186
+ $fix) {
4187
+ $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
4188
+ }
4189
+ }
38734190
38744191 # check for static char foo[] = "bar" declarations.
38754192 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
38764193 WARN("STATIC_CONST_CHAR_ARRAY",
38774194 "static char array declaration should probably be static const char\n" .
38784195 $herecurr);
3879
- }
4196
+ }
38804197
38814198 # check for const <foo> const where <foo> is not a pointer or array type
38824199 if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
....@@ -3911,7 +4228,7 @@
39114228 }
39124229
39134230 # check for function declarations without arguments like "int foo()"
3914
- if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
4231
+ if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
39154232 if (ERROR("FUNCTION_WITHOUT_ARGS",
39164233 "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
39174234 $fix) {
....@@ -4022,15 +4339,6 @@
40224339 "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
40234340 }
40244341
4025
- if ($line =~ /\bpr_warning\s*\(/) {
4026
- if (WARN("PREFER_PR_LEVEL",
4027
- "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
4028
- $fix) {
4029
- $fixed[$fixlinenr] =~
4030
- s/\bpr_warning\b/pr_warn/;
4031
- }
4032
- }
4033
-
40344342 if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
40354343 my $orig = $1;
40364344 my $level = lc($orig);
....@@ -4040,12 +4348,29 @@
40404348 "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
40414349 }
40424350
4351
+# trace_printk should not be used in production code.
4352
+ if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
4353
+ WARN("TRACE_PRINTK",
4354
+ "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
4355
+ }
4356
+
40434357 # ENOSYS means "bad syscall nr" and nothing else. This will have a small
40444358 # number of false positives, but assembly files are not checked, so at
40454359 # least the arch entry code will not trigger this warning.
40464360 if ($line =~ /\bENOSYS\b/) {
40474361 WARN("ENOSYS",
40484362 "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
4363
+ }
4364
+
4365
+# ENOTSUPP is not a standard error code and should be avoided in new patches.
4366
+# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
4367
+# Similarly to ENOSYS warning a small number of false positives is expected.
4368
+ if (!$file && $line =~ /\bENOTSUPP\b/) {
4369
+ if (WARN("ENOTSUPP",
4370
+ "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
4371
+ $fix) {
4372
+ $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
4373
+ }
40494374 }
40504375
40514376 # function brace can't be on same line, except for #defines of do while,
....@@ -4488,7 +4813,7 @@
44884813 ($op eq '>' &&
44894814 $ca =~ /<\S+\@\S+$/))
44904815 {
4491
- $ok = 1;
4816
+ $ok = 1;
44924817 }
44934818
44944819 # for asm volatile statements
....@@ -4584,7 +4909,7 @@
45844909
45854910 # closing brace should have a space following it when it has anything
45864911 # on the line
4587
- if ($line =~ /}(?!(?:,|;|\)))\S/) {
4912
+ if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
45884913 if (ERROR("SPACING",
45894914 "space required after that close brace '}'\n" . $herecurr) &&
45904915 $fix) {
....@@ -4693,6 +5018,17 @@
46935018 $fixed[$fixlinenr] =~
46945019 s/^(.)\s+/$1/;
46955020 }
5021
+ }
5022
+
5023
+# check if a statement with a comma should be two statements like:
5024
+# foo = bar(), /* comma should be semicolon */
5025
+# bar = baz();
5026
+ if (defined($stat) &&
5027
+ $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
5028
+ my $cnt = statement_rawlines($stat);
5029
+ my $herectx = get_stat_here($linenr, $cnt, $here);
5030
+ WARN("SUSPECT_COMMA_SEMICOLON",
5031
+ "Possible comma where semicolon could be used\n" . $herectx);
46965032 }
46975033
46985034 # return is not a function
....@@ -4815,15 +5151,37 @@
48155151 my ($s, $c) = ($stat, $cond);
48165152
48175153 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4818
- ERROR("ASSIGN_IN_IF",
4819
- "do not use assignment in if condition\n" . $herecurr);
5154
+ if (ERROR("ASSIGN_IN_IF",
5155
+ "do not use assignment in if condition\n" . $herecurr) &&
5156
+ $fix && $perl_version_ok) {
5157
+ if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
5158
+ my $space = $1;
5159
+ my $not = $2;
5160
+ my $statement = $3;
5161
+ my $assigned = $4;
5162
+ my $test = $8;
5163
+ my $against = $9;
5164
+ my $brace = $15;
5165
+ fix_delete_line($fixlinenr, $rawline);
5166
+ fix_insert_line($fixlinenr, "$space$statement;");
5167
+ my $newline = "${space}if (";
5168
+ $newline .= '!' if defined($not);
5169
+ $newline .= '(' if (defined $not && defined($test) && defined($against));
5170
+ $newline .= "$assigned";
5171
+ $newline .= " $test $against" if (defined($test) && defined($against));
5172
+ $newline .= ')' if (defined $not && defined($test) && defined($against));
5173
+ $newline .= ')';
5174
+ $newline .= " {" if (defined($brace));
5175
+ fix_insert_line($fixlinenr + 1, $newline);
5176
+ }
5177
+ }
48205178 }
48215179
48225180 # Find out what is on the end of the line after the
48235181 # conditional.
48245182 substr($s, 0, length($c), '');
48255183 $s =~ s/\n.*//g;
4826
- $s =~ s/$;//g; # Remove any comments
5184
+ $s =~ s/$;//g; # Remove any comments
48275185 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
48285186 $c !~ /}\s*while\s*/)
48295187 {
....@@ -4862,7 +5220,7 @@
48625220 # if and else should not have general statements after it
48635221 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
48645222 my $s = $1;
4865
- $s =~ s/$;//g; # Remove any comments
5223
+ $s =~ s/$;//g; # Remove any comments
48665224 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
48675225 ERROR("TRAILING_STATEMENTS",
48685226 "trailing statements should be on next line\n" . $herecurr);
....@@ -4934,24 +5292,14 @@
49345292 while ($line =~ m{($Constant|$Lval)}g) {
49355293 my $var = $1;
49365294
4937
-#gcc binary extension
4938
- if ($var =~ /^$Binary$/) {
4939
- if (WARN("GCC_BINARY_CONSTANT",
4940
- "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4941
- $fix) {
4942
- my $hexval = sprintf("0x%x", oct($var));
4943
- $fixed[$fixlinenr] =~
4944
- s/\b$var\b/$hexval/;
4945
- }
4946
- }
4947
-
49485295 #CamelCase
49495296 if ($var !~ /^$Constant$/ &&
49505297 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
49515298 #Ignore Page<foo> variants
49525299 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
4953
-#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
4954
- $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
5300
+#Ignore SI style variants like nS, mV and dB
5301
+#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5302
+ $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
49555303 #Ignore some three character SI units explicitly, like MiB and KHz
49565304 $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
49575305 while ($var =~ m{($Ident)}g) {
....@@ -5042,13 +5390,13 @@
50425390 $dstat =~ s/\s*$//s;
50435391
50445392 # Flatten any parentheses and braces
5045
- while ($dstat =~ s/\([^\(\)]*\)/1/ ||
5046
- $dstat =~ s/\{[^\{\}]*\}/1/ ||
5047
- $dstat =~ s/.\[[^\[\]]*\]/1/)
5393
+ while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
5394
+ $dstat =~ s/\{[^\{\}]*\}/1u/ ||
5395
+ $dstat =~ s/.\[[^\[\]]*\]/1u/)
50485396 {
50495397 }
50505398
5051
- # Flatten any obvious string concatentation.
5399
+ # Flatten any obvious string concatenation.
50525400 while ($dstat =~ s/($String)\s*$Ident/$1/ ||
50535401 $dstat =~ s/$Ident\s*($String)/$1/)
50545402 {
....@@ -5085,6 +5433,7 @@
50855433 $dstat !~ /^\.$Ident\s*=/ && # .foo =
50865434 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
50875435 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
5436
+ $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...}
50885437 $dstat !~ /^for\s*$Constant$/ && # for (...)
50895438 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
50905439 $dstat !~ /^do\s*{/ && # do {...
....@@ -5126,7 +5475,7 @@
51265475 next if ($arg =~ /\.\.\./);
51275476 next if ($arg =~ /^type$/i);
51285477 my $tmp_stmt = $define_stmt;
5129
- $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
5478
+ $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
51305479 $tmp_stmt =~ s/\#+\s*$arg\b//g;
51315480 $tmp_stmt =~ s/\b$arg\s*\#\#//g;
51325481 my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
....@@ -5525,7 +5874,8 @@
55255874 my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
55265875 # print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
55275876
5528
- if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) {
5877
+ if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
5878
+ $s !~ /\b__GFP_NOWARN\b/ ) {
55295879 WARN("OOM_MESSAGE",
55305880 "Possible unnecessary 'out of memory' message\n" . $hereprev);
55315881 }
....@@ -5646,7 +5996,7 @@
56465996 # ignore udelay's < 10, however
56475997 if (! ($delay < 10) ) {
56485998 CHK("USLEEP_RANGE",
5649
- "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
5999
+ "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
56506000 }
56516001 if ($delay > 2000) {
56526002 WARN("LONG_UDELAY",
....@@ -5658,7 +6008,7 @@
56586008 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
56596009 if ($1 < 20) {
56606010 WARN("MSLEEP",
5661
- "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
6011
+ "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
56626012 }
56636013 }
56646014
....@@ -5706,8 +6056,7 @@
57066056 my $barriers = qr{
57076057 mb|
57086058 rmb|
5709
- wmb|
5710
- read_barrier_depends
6059
+ wmb
57116060 }x;
57126061 my $barrier_stems = qr{
57136062 mb__before_atomic|
....@@ -5748,10 +6097,12 @@
57486097 }
57496098 }
57506099
5751
-# check for smp_read_barrier_depends and read_barrier_depends
5752
- if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
5753
- WARN("READ_BARRIER_DEPENDS",
5754
- "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
6100
+# check for data_race without a comment.
6101
+ if ($line =~ /\bdata_race\s*\(/) {
6102
+ if (!ctx_has_comment($first_line, $linenr)) {
6103
+ WARN("DATA_RACE",
6104
+ "data_race without comment\n" . $herecurr);
6105
+ }
57556106 }
57566107
57576108 # check of hardware specific defines
....@@ -5805,6 +6156,18 @@
58056156 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
58066157 WARN("PREFER_ALIGNED",
58076158 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
6159
+ }
6160
+
6161
+# Check for __attribute__ section, prefer __section
6162
+ if ($realfile !~ m@\binclude/uapi/@ &&
6163
+ $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
6164
+ my $old = substr($rawline, $-[1], $+[1] - $-[1]);
6165
+ my $new = substr($old, 1, -1);
6166
+ if (WARN("PREFER_SECTION",
6167
+ "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
6168
+ $fix) {
6169
+ $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
6170
+ }
58086171 }
58096172
58106173 # Check for __attribute__ format(printf, prefer __printf
....@@ -5922,14 +6285,18 @@
59226285 for (my $count = $linenr; $count <= $lc; $count++) {
59236286 my $specifier;
59246287 my $extension;
6288
+ my $qualifier;
59256289 my $bad_specifier = "";
59266290 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
59276291 $fmt =~ s/%%//g;
59286292
5929
- while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) {
6293
+ while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
59306294 $specifier = $1;
59316295 $extension = $2;
5932
- if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOx]/) {
6296
+ $qualifier = $3;
6297
+ if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
6298
+ ($extension eq "f" &&
6299
+ defined $qualifier && $qualifier !~ /^w/)) {
59336300 $bad_specifier = $specifier;
59346301 last;
59356302 }
....@@ -5946,7 +6313,6 @@
59466313 my $ext_type = "Invalid";
59476314 my $use = "";
59486315 if ($bad_specifier =~ /p[Ff]/) {
5949
- $ext_type = "Deprecated";
59506316 $use = " - use %pS instead";
59516317 $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
59526318 }
....@@ -6049,11 +6415,11 @@
60496415 my $max = $7;
60506416 if ($min eq $max) {
60516417 WARN("USLEEP_RANGE",
6052
- "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
6418
+ "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
60536419 } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
60546420 $min > $max) {
60556421 WARN("USLEEP_RANGE",
6056
- "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
6422
+ "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
60576423 }
60586424 }
60596425
....@@ -6110,8 +6476,7 @@
61106476 if (defined $cond) {
61116477 substr($s, 0, length($cond), '');
61126478 }
6113
- if ($s =~ /^\s*;/ &&
6114
- $function_name ne 'uninitialized_var')
6479
+ if ($s =~ /^\s*;/)
61156480 {
61166481 WARN("AVOID_EXTERNS",
61176482 "externs should be avoided in .c files\n" . $herecurr);
....@@ -6172,12 +6537,12 @@
61726537
61736538 if (!grep(/$name/, @setup_docs)) {
61746539 CHK("UNDOCUMENTED_SETUP",
6175
- "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
6540
+ "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
61766541 }
61776542 }
61786543
6179
-# check for pointless casting of kmalloc return
6180
- if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
6544
+# check for pointless casting of alloc functions
6545
+ if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
61816546 WARN("UNNECESSARY_CASTS",
61826547 "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
61836548 }
....@@ -6185,7 +6550,7 @@
61856550 # alloc style
61866551 # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
61876552 if ($perl_version_ok &&
6188
- $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6553
+ $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
61896554 CHK("ALLOC_SIZEOF_STRUCT",
61906555 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
61916556 }
....@@ -6254,38 +6619,41 @@
62546619 }
62556620 }
62566621
6622
+# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
6623
+ if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
6624
+ WARN("IS_ENABLED_CONFIG",
6625
+ "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
6626
+ }
6627
+
62576628 # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
6258
- if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
6629
+ if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
62596630 my $config = $1;
62606631 if (WARN("PREFER_IS_ENABLED",
6261
- "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
6632
+ "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
62626633 $fix) {
62636634 $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
62646635 }
62656636 }
62666637
6267
-# check for case / default statements not preceded by break/fallthrough/switch
6268
- if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6269
- my $has_break = 0;
6270
- my $has_statement = 0;
6271
- my $count = 0;
6272
- my $prevline = $linenr;
6273
- while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6274
- $prevline--;
6275
- my $rline = $rawlines[$prevline - 1];
6276
- my $fline = $lines[$prevline - 1];
6277
- last if ($fline =~ /^\@\@/);
6278
- next if ($fline =~ /^\-/);
6279
- next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6280
- $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6281
- next if ($fline =~ /^.[\s$;]*$/);
6282
- $has_statement = 1;
6283
- $count++;
6284
- $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
6285
- }
6286
- if (!$has_break && $has_statement) {
6287
- WARN("MISSING_BREAK",
6288
- "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6638
+# check for /* fallthrough */ like comment, prefer fallthrough;
6639
+ my @fallthroughs = (
6640
+ 'fallthrough',
6641
+ '@fallthrough@',
6642
+ 'lint -fallthrough[ \t]*',
6643
+ 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
6644
+ '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
6645
+ 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6646
+ 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6647
+ );
6648
+ if ($raw_comment ne '') {
6649
+ foreach my $ft (@fallthroughs) {
6650
+ if ($raw_comment =~ /$ft/) {
6651
+ my $msg_level = \&WARN;
6652
+ $msg_level = \&CHK if ($file);
6653
+ &{$msg_level}("PREFER_FALLTHROUGH",
6654
+ "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
6655
+ last;
6656
+ }
62896657 }
62906658 }
62916659
....@@ -6348,19 +6716,6 @@
63486716 }
63496717 }
63506718
6351
-# check for bool bitfields
6352
- if ($sline =~ /^.\s+bool\s*$Ident\s*:\s*\d+\s*;/) {
6353
- WARN("BOOL_BITFIELD",
6354
- "Avoid using bool as bitfield. Prefer bool bitfields as unsigned int or u<8|16|32>\n" . $herecurr);
6355
- }
6356
-
6357
-# check for bool use in .h files
6358
- if ($realfile =~ /\.h$/ &&
6359
- $sline =~ /^.\s+bool\s*$Ident\s*(?::\s*d+\s*)?;/) {
6360
- CHK("BOOL_MEMBER",
6361
- "Avoid using bool structure members because of possible alignment issues - see: https://lkml.org/lkml/2017/11/21/384\n" . $herecurr);
6362
- }
6363
-
63646719 # check for semaphores initialized locked
63656720 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
63666721 WARN("CONSIDER_COMPLETION",
....@@ -6379,9 +6734,24 @@
63796734 "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
63806735 }
63816736
6737
+# check for spin_is_locked(), suggest lockdep instead
6738
+ if ($line =~ /\bspin_is_locked\(/) {
6739
+ WARN("USE_LOCKDEP",
6740
+ "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
6741
+ }
6742
+
6743
+# check for deprecated apis
6744
+ if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
6745
+ my $deprecated_api = $1;
6746
+ my $new_api = $deprecated_apis{$deprecated_api};
6747
+ WARN("DEPRECATED_API",
6748
+ "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
6749
+ }
6750
+
63826751 # check for various structs that are normally const (ops, kgdb, device_tree)
63836752 # and avoid what seem like struct definitions 'struct foo {'
6384
- if ($line !~ /\bconst\b/ &&
6753
+ if (defined($const_structs) &&
6754
+ $line !~ /\bconst\b/ &&
63856755 $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
63866756 WARN("CONST_STRUCT",
63876757 "struct $1 should normally be const\n" . $herecurr);
....@@ -6411,6 +6781,12 @@
64116781 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
64126782 WARN("LIKELY_MISUSE",
64136783 "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6784
+ }
6785
+
6786
+# nested likely/unlikely calls
6787
+ if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
6788
+ WARN("LIKELY_MISUSE",
6789
+ "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
64146790 }
64156791
64166792 # whine mightly about in_atomic
....@@ -6572,6 +6948,12 @@
65726948 "unknown module license " . $extracted_string . "\n" . $herecurr);
65736949 }
65746950 }
6951
+
6952
+# check for sysctl duplicate constants
6953
+ if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
6954
+ WARN("DUPLICATED_SYSCTL_CONST",
6955
+ "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
6956
+ }
65756957 }
65766958
65776959 # If we have no input at all, then there is nothing to report on
....@@ -6600,9 +6982,33 @@
66006982 if ($signoff == 0) {
66016983 ERROR("MISSING_SIGN_OFF",
66026984 "Missing Signed-off-by: line(s)\n");
6603
- } elsif (!$authorsignoff) {
6604
- WARN("NO_AUTHOR_SIGN_OFF",
6605
- "Missing Signed-off-by: line by nominal patch author '$author'\n");
6985
+ } elsif ($authorsignoff != 1) {
6986
+ # authorsignoff values:
6987
+ # 0 -> missing sign off
6988
+ # 1 -> sign off identical
6989
+ # 2 -> names and addresses match, comments mismatch
6990
+ # 3 -> addresses match, names different
6991
+ # 4 -> names match, addresses different
6992
+ # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
6993
+
6994
+ my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
6995
+
6996
+ if ($authorsignoff == 0) {
6997
+ ERROR("NO_AUTHOR_SIGN_OFF",
6998
+ "Missing Signed-off-by: line by nominal patch author '$author'\n");
6999
+ } elsif ($authorsignoff == 2) {
7000
+ CHK("FROM_SIGN_OFF_MISMATCH",
7001
+ "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
7002
+ } elsif ($authorsignoff == 3) {
7003
+ WARN("FROM_SIGN_OFF_MISMATCH",
7004
+ "From:/Signed-off-by: email name mismatch: $sob_msg\n");
7005
+ } elsif ($authorsignoff == 4) {
7006
+ WARN("FROM_SIGN_OFF_MISMATCH",
7007
+ "From:/Signed-off-by: email address mismatch: $sob_msg\n");
7008
+ } elsif ($authorsignoff == 5) {
7009
+ WARN("FROM_SIGN_OFF_MISMATCH",
7010
+ "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
7011
+ }
66067012 }
66077013 }
66087014