scripts: update checkpatch based on current linux kernel version

This squashes and applies the Linux diffs to scripts/checkpatch.pl
between Linux commit 16fbf79b0f83bc75 ("Linux 5.6-rc7") and
9123e3a74ec7b93 ("Linux 5.9-rc1") except for commits identified below.

The last 1000 commits to Zephyr master were compared for checkpatch
output differences between the previous Zephyr version and this
version.  One new diagnostic about function declarations with an empty
parameter-list was introduced (FUNCTION_WITHOUT_ARGS).  The text of an
existing diagnostic was changed (DT_SPLIT_BINDING_PATCH).  The text of
LONG_LINE diagnostics was enhanced to provide the actual line length.

Linux commit dfa05c28ca7ffc0a ("checkpatch: remove email address
comment from email address comparisons") was removed because
differences in the scripts resulted in false signed-off-by check
diagnostics when a full name included characters not in Basic Latin,
due to changes in how the author name was extracted.  Earlier upstream
changes not integrated into Zephyr may be required.

Linux commit b95692f8b3000166 ("checkpatch: prefer fallthrough; over
fallthrough comments") was removed because Zephyr doesn't support the
upstream pseudo keyword.

Linux commit bdc48fa11e46f867 ("checkpatch/coding-style: deprecate
80-column warning") was edited to not actually change the 80-column
maximum line limit as this change has not been mooted for Zephyr.

Linux commit ced69da1db0b57bb ("checkpatch: fix CONST_STRUCT when
const_structs.checkpatch is missing") was edited to the CONST_STRUCT
file as that's not supported in Zephyr.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
Peter A. Bigot 2020-08-10 10:37:32 -05:00 committed by Anas Nashif
parent 34ddb8cfa8
commit e49e3c8fef

View file

@ -60,11 +60,12 @@ my $spelling_file = "$D/spelling.txt";
my $codespell = 0;
my $codespellfile = "/usr/share/codespell/dictionary.txt";
my $conststructsfile = "$D/const_structs.checkpatch";
my $typedefsfile = "";
my $typedefsfile;
my $color = "auto";
my $allow_c99_comments = 0;
# git output parsing needs US English output, so first set backtick child process LANGUAGE
my $git_command ='export LANGUAGE=en_US.UTF-8; git';
my $tabsize = 8;
sub help {
my ($exitcode) = @_;
@ -98,8 +99,11 @@ Options:
--ignore TYPE(,TYPE2...) ignore various comma separated message types
--exclude DIR(,DIR22...) exclude directories
--show-types show the specific message type in the output
--max-line-length=n set the maximum line length, if exceeded, warn
--max-line-length=n set the maximum line length, (default $max_line_length)
if exceeded, warn on patches
requires --strict for use with --file
--min-conf-desc-length=n set the min description length, if shorter, warn
--tab-size=n set the number of spaces for tab (default $tabsize)
--root=PATH PATH to the kernel tree root
--no-summary suppress the per-file summary
--mailback only produce a report in case of warnings/errors
@ -218,6 +222,7 @@ GetOptions(
'list-types!' => \$list_types,
'max-line-length=i' => \$max_line_length,
'min-conf-desc-length=i' => \$min_conf_desc_length,
'tab-size=i' => \$tabsize,
'root=s' => \$root,
'summary!' => \$summary,
'mailback!' => \$mailback,
@ -244,6 +249,8 @@ list_types(0) if ($list_types);
$fix = 1 if ($fix_inplace);
$check_orig = $check;
die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
my $exit = 0;
my $perl_version_ok = 1;
@ -267,9 +274,12 @@ if ($color =~ /^[01]$/) {
} elsif ($color =~ /^auto$/i) {
$color = (-t STDOUT);
} else {
die "Invalid color mode: $color\n";
die "$P: Invalid color mode: $color\n";
}
# skip TAB size 1 to avoid additional checks on $tabsize - 1
die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
sub hash_save_array_words {
my ($hashRef, $arrayRef) = @_;
@ -476,7 +486,7 @@ our $allocFunctions = qr{(?x:
(?:kv|k|v)[czm]alloc(?:_node|_array)? |
kstrdup(?:_const)? |
kmemdup(?:_nul)?) |
(?:\w+)?alloc_skb(?:ip_align)? |
(?:\w+)?alloc_skb(?:_ip_align)? |
# dev_alloc_skb/netdev_alloc_skb, et al
dma_alloc_coherent
)};
@ -581,6 +591,8 @@ our @mode_permission_funcs = (
["__ATTR", 2],
);
my $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
#Create a search pattern for all these functions to speed up a loop below
our $mode_perms_search = "";
foreach my $entry (@mode_permission_funcs) {
@ -749,7 +761,7 @@ sub read_words {
next;
}
$$wordsRef .= '|' if ($$wordsRef ne "");
$$wordsRef .= '|' if (defined $$wordsRef);
$$wordsRef .= $line;
}
close($file);
@ -759,16 +771,18 @@ sub read_words {
return 0;
}
my $const_structs = "";
#read_words(\$const_structs, $conststructsfile)
# or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
my $const_structs;
#if (show_type("CONST_STRUCT")) {
# read_words(\$const_structs, $conststructsfile)
# or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
#}
my $typeOtherTypedefs = "";
if (length($typedefsfile)) {
if (defined($typedefsfile)) {
my $typeOtherTypedefs;
read_words(\$typeOtherTypedefs, $typedefsfile)
or warn "No additional types will be considered - file '$typedefsfile': $!\n";
$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
}
$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
sub build_types {
my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
@ -807,12 +821,12 @@ sub build_types {
}x;
$Type = qr{
$NonptrType
(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
(?:\s+$Inline|\s+$Modifier)*
}x;
$TypeMisordered = qr{
$NonptrTypeMisordered
(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
(?:\s+$Inline|\s+$Modifier)*
}x;
$Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
@ -833,7 +847,6 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
our $declaration_macros = qr{(?x:
(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
)};
@ -1055,6 +1068,7 @@ for my $filename (@ARGV) {
while (<$FILE>) {
chomp;
push(@rawlines, $_);
$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
}
close($FILE);
@ -1220,7 +1234,7 @@ sub expand_tabs {
if ($c eq "\t") {
$res .= ' ';
$n++;
for (; ($n % 8) != 0; $n++) {
for (; ($n % $tabsize) != 0; $n++) {
$res .= ' ';
}
next;
@ -1649,8 +1663,16 @@ sub ctx_statement_level {
sub ctx_locate_comment {
my ($first_line, $end_line) = @_;
# If c99 comment on the current line, or the line before or after
my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
return $current_comment if (defined $current_comment);
($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
return $current_comment if (defined $current_comment);
($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
return $current_comment if (defined $current_comment);
# Catch a comment on the end of the line itself.
my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
return $current_comment if (defined $current_comment);
# Look through the context and try and figure out if there is a
@ -2233,7 +2255,7 @@ sub string_find_replace {
sub tabify {
my ($leading) = @_;
my $source_indent = 8;
my $source_indent = $tabsize;
my $max_spaces_before_tab = $source_indent - 1;
my $spaces_to_tab = " " x $source_indent;
@ -2297,6 +2319,7 @@ sub process {
my $is_binding_patch = -1;
my $in_header_lines = $file ? 0 : 1;
my $in_commit_log = 0; #Scanning lines before patch
my $has_patch_separator = 0; #Found a --- line
my $has_commit_log = 0; #Encountered lines before patch
my $commit_log_lines = 0; #Number of commit log lines
my $commit_log_possible_stack_dump = 0;
@ -2355,7 +2378,7 @@ sub process {
if ($rawline=~/^\+\+\+\s+(\S+)/) {
$setup_docs = 0;
if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
$setup_docs = 1;
}
#next;
@ -2563,7 +2586,7 @@ sub process {
if (($last_binding_patch != -1) &&
($last_binding_patch ^ $is_binding_patch)) {
WARN("DT_SPLIT_BINDING_PATCH",
"DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
"DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
}
}
@ -2631,6 +2654,12 @@ sub process {
}
}
# Check for patch separator
if ($line =~ /^---$/) {
$has_patch_separator = 1;
$in_commit_log = 0;
}
# Check if CODEOWNERS is being updated. If so, there's probably no need to
# emit the "does CODEOWNERS need updating?" message on file add/move/delete
if ($line =~ /^\s*CODEOWNERS\s*\|/) {
@ -2732,10 +2761,10 @@ sub process {
"A patch subject line should describe the change not the tool that found it\n" . $herecurr);
}
# Check for unwanted Gerrit info
if ($in_commit_log && $line =~ /^\s*change-id:/i) {
# Check for Gerrit Change-Ids not in any patch context
if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
ERROR("GERRIT_CHANGE_ID",
"Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
"Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
}
# Check if the commit log is in a possible stack dump
@ -2773,7 +2802,7 @@ sub process {
# Check for git id commit length and improperly formed commit descriptions
if ($in_commit_log && !$commit_log_possible_stack_dump &&
$line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
$line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
$line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
@ -2995,11 +3024,7 @@ sub process {
if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
$is_start = 1;
} elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
if ($lines[$ln - 1] =~ "---help---") {
WARN("CONFIG_DESCRIPTION",
"prefer 'help' over '---help---' for new help texts\n" . $herecurr);
}
} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
$length = -1;
}
@ -3026,14 +3051,43 @@ sub process {
#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
}
# check for MAINTAINERS entries that don't have the right form
if ($realfile =~ /^MAINTAINERS$/ &&
$rawline =~ /^\+[A-Z]:/ &&
$rawline !~ /^\+[A-Z]:\t\S/) {
if (WARN("MAINTAINERS_STYLE",
"MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
# check MAINTAINERS entries
if ($realfile =~ /^MAINTAINERS$/) {
# check MAINTAINERS entries for the right form
if ($rawline =~ /^\+[A-Z]:/ &&
$rawline !~ /^\+[A-Z]:\t\S/) {
if (WARN("MAINTAINERS_STYLE",
"MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
}
}
# check MAINTAINERS entries for the right ordering too
my $preferred_order = 'MRLSWQBCPTFXNK';
if ($rawline =~ /^\+[A-Z]:/ &&
$prevrawline =~ /^[\+ ][A-Z]:/) {
$rawline =~ /^\+([A-Z]):\s*(.*)/;
my $cur = $1;
my $curval = $2;
$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
my $prev = $1;
my $prevval = $2;
my $curindex = index($preferred_order, $cur);
my $previndex = index($preferred_order, $prev);
if ($curindex < 0) {
WARN("MAINTAINERS_STYLE",
"Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
} else {
if ($previndex >= 0 && $curindex < $previndex) {
WARN("MAINTAINERS_STYLE",
"Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
} elsif ((($prev eq 'F' && $cur eq 'F') ||
($prev eq 'X' && $cur eq 'X')) &&
($prevval cmp $curval) > 0) {
WARN("MAINTAINERS_STYLE",
"Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
}
}
}
}
@ -3105,7 +3159,7 @@ sub process {
$comment = '/*';
} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
$comment = '//';
} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
$comment = '#';
} elsif ($realfile =~ /\.rst$/) {
$comment = '..';
@ -3129,6 +3183,17 @@ sub process {
WARN("SPDX_LICENSE_TAG",
"'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
}
if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
my $msg_level = \&WARN;
$msg_level = \&CHK if ($file);
if (&{$msg_level}("SPDX_LICENSE_TAG",
"DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
}
}
}
}
}
@ -3201,8 +3266,10 @@ sub process {
if ($msg_type ne "" &&
(show_type("LONG_LINE") || show_type($msg_type))) {
WARN($msg_type,
"line over $max_line_length characters\n" . $herecurr);
my $msg_level = \&WARN;
$msg_level = \&CHK if ($file);
&{$msg_level}($msg_type,
"line length of $length exceeds $max_line_length columns\n" . $herecurr);
}
}
@ -3216,7 +3283,7 @@ sub process {
next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
# at the beginning of a line any tabs must come first and anything
# more than 8 must use tabs.
# more than $tabsize must use tabs.
if ($rawline =~ /^\+\s* \t\s*\S/ ||
$rawline =~ /^\+\s* \s*/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
@ -3228,6 +3295,42 @@ sub process {
}
}
# check for repeated words separated by a single space
if ($rawline =~ /^\+/) {
while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
my $first = $1;
my $second = $2;
if ($first =~ /(?:struct|union|enum)/) {
pos($rawline) += length($first) + length($second) + 1;
next;
}
next if ($first ne $second);
next if ($first eq 'long');
if (WARN("REPEATED_WORD",
"Possible repeated word: '$first'\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
}
}
# if it's a repeated word on consecutive lines in a comment block
if ($prevline =~ /$;+\s*$/ &&
$prevrawline =~ /($word_pattern)\s*$/) {
my $last_word = $1;
if ($rawline =~ /^\+\s*\*\s*$last_word /) {
if (WARN("REPEATED_WORD",
"Possible repeated word: '$last_word'\n" . $hereprev) &&
$fix) {
$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
}
}
}
}
# check for space before tabs.
if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
@ -3235,7 +3338,7 @@ sub process {
"please, no space before tabs\n" . $herevet) &&
$fix) {
while ($fixed[$fixlinenr] =~
s/(^\+.*) {8,8}\t/$1\t\t/) {}
s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
while ($fixed[$fixlinenr] =~
s/(^\+.*) +\t/$1\t/) {}
}
@ -3257,11 +3360,11 @@ sub process {
if ($perl_version_ok &&
$sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
my $indent = length($1);
if ($indent % 8) {
if ($indent % $tabsize) {
if (WARN("TABSTOP",
"Statements should start on a tabstop\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
}
}
}
@ -3279,8 +3382,8 @@ sub process {
my $newindent = $2;
my $goodtabindent = $oldindent .
"\t" x ($pos / 8) .
" " x ($pos % 8);
"\t" x ($pos / $tabsize) .
" " x ($pos % $tabsize);
my $goodspaceindent = $oldindent . " " x $pos;
if ($newindent ne $goodtabindent &&
@ -3751,11 +3854,11 @@ sub process {
#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";
if ($check && $s ne '' &&
(($sindent % 8) != 0 ||
(($sindent % $tabsize) != 0 ||
($sindent < $indent) ||
($sindent == $indent &&
($s !~ /^\s*(?:\}|\{|else\b)/)) ||
($sindent > $indent + 8))) {
($sindent > $indent + $tabsize))) {
WARN("SUSPECT_CODE_INDENT",
"suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
}
@ -4032,7 +4135,7 @@ sub process {
}
# check for function declarations without arguments like "int foo()"
if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
if (ERROR("FUNCTION_WITHOUT_ARGS",
"Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
$fix) {
@ -4160,6 +4263,17 @@ sub process {
"ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
}
# ENOTSUPP is not a standard error code and should be avoided in new patches.
# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
# Similarly to ENOSYS warning a small number of false positives is expected.
if (!$file && $line =~ /\bENOTSUPP\b/) {
if (WARN("ENOTSUPP",
"ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
}
}
# function brace can't be on same line, except for #defines of do while,
# or if closed on same line
if ($perl_version_ok &&
@ -4601,7 +4715,7 @@ sub process {
($op eq '>' &&
$ca =~ /<\S+\@\S+$/))
{
$ok = 1;
$ok = 1;
}
# for asm volatile statements
@ -4928,15 +5042,37 @@ sub process {
my ($s, $c) = ($stat, $cond);
if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
ERROR("ASSIGN_IN_IF",
"do not use assignment in if condition\n" . $herecurr);
if (ERROR("ASSIGN_IN_IF",
"do not use assignment in if condition\n" . $herecurr) &&
$fix && $perl_version_ok) {
if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
my $space = $1;
my $not = $2;
my $statement = $3;
my $assigned = $4;
my $test = $8;
my $against = $9;
my $brace = $15;
fix_delete_line($fixlinenr, $rawline);
fix_insert_line($fixlinenr, "$space$statement;");
my $newline = "${space}if (";
$newline .= '!' if defined($not);
$newline .= '(' if (defined $not && defined($test) && defined($against));
$newline .= "$assigned";
$newline .= " $test $against" if (defined($test) && defined($against));
$newline .= ')' if (defined $not && defined($test) && defined($against));
$newline .= ')';
$newline .= " {" if (defined($brace));
fix_insert_line($fixlinenr + 1, $newline);
}
}
}
# Find out what is on the end of the line after the
# conditional.
substr($s, 0, length($c), '');
$s =~ s/\n.*//g;
$s =~ s/$;//g; # Remove any comments
$s =~ s/$;//g; # Remove any comments
if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
$c !~ /}\s*while\s*/)
{
@ -4975,7 +5111,7 @@ sub process {
# if and else should not have general statements after it
if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
my $s = $1;
$s =~ s/$;//g; # Remove any comments
$s =~ s/$;//g; # Remove any comments
if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
ERROR("TRAILING_STATEMENTS",
"trailing statements should be on next line\n" . $herecurr);
@ -5151,7 +5287,7 @@ sub process {
{
}
# Flatten any obvious string concatentation.
# Flatten any obvious string concatenation.
while ($dstat =~ s/($String)\s*$Ident/$1/ ||
$dstat =~ s/$Ident\s*($String)/$1/)
{
@ -5810,8 +5946,7 @@ sub process {
my $barriers = qr{
mb|
rmb|
wmb|
read_barrier_depends
wmb
}x;
my $barrier_stems = qr{
mb__before_atomic|
@ -5852,10 +5987,12 @@ sub process {
}
}
# check for smp_read_barrier_depends and read_barrier_depends
if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
WARN("READ_BARRIER_DEPENDS",
"$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
# check for data_race without a comment.
if ($line =~ /\bdata_race\s*\(/) {
if (!ctx_has_comment($first_line, $linenr)) {
WARN("DATA_RACE",
"data_race without comment\n" . $herecurr);
}
}
# check of hardware specific defines
@ -6228,8 +6365,7 @@ sub process {
if (defined $cond) {
substr($s, 0, length($cond), '');
}
if ($s =~ /^\s*;/ &&
$function_name ne 'uninitialized_var')
if ($s =~ /^\s*;/)
{
WARN("AVOID_EXTERNS",
"externs should be avoided in .c files\n" . $herecurr);
@ -6290,7 +6426,7 @@ sub process {
if (!grep(/$name/, @setup_docs)) {
CHK("UNDOCUMENTED_SETUP",
"__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
"__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
}
}
@ -6372,6 +6508,12 @@ sub process {
}
}
# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^CONFIG_/) {
WARN("IS_ENABLED_CONFIG",
"IS_ENABLED($1) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr);
}
# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
my $config = $1;
@ -6382,31 +6524,6 @@ sub process {
}
}
# check for case / default statements not preceded by break/fallthrough/switch
if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
my $has_break = 0;
my $has_statement = 0;
my $count = 0;
my $prevline = $linenr;
while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
$prevline--;
my $rline = $rawlines[$prevline - 1];
my $fline = $lines[$prevline - 1];
last if ($fline =~ /^\@\@/);
next if ($fline =~ /^\-/);
next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
next if ($fline =~ /^.[\s$;]*$/);
$has_statement = 1;
$count++;
$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
}
if (!$has_break && $has_statement) {
WARN("MISSING_BREAK",
"Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
}
}
# check for switch/default statements without a break;
if ($perl_version_ok &&
defined $stat &&
@ -6500,7 +6617,8 @@ sub process {
# check for various structs that are normally const (ops, kgdb, device_tree)
# and avoid what seem like struct definitions 'struct foo {'
if ($line !~ /\bconst\b/ &&
if (defined($const_structs) &&
$line !~ /\bconst\b/ &&
$line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
WARN("CONST_STRUCT",
"struct $1 should normally be const\n" . $herecurr);