checkpatch: update to Linux version v5.17

Minimal, SOF-only differences with v5.17

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
This commit is contained in:
Marc Herbert 2022-05-11 23:59:33 +00:00 committed by Liam Girdwood
parent d0fe4933f4
commit af6586bd81
1 changed files with 229 additions and 96 deletions

View File

@ -24,6 +24,9 @@ use Getopt::Long qw(:config no_auto_abbrev);
my $SOF = 1; # enables SOF-specific behaviour
my $quiet = 0;
my $verbose = 0;
my %verbose_messages = ();
my %verbose_emitted = ();
my $tree = 1;
my $chk_signoff = 1;
my $chk_patch = 1;
@ -63,6 +66,7 @@ my $codespell = 0;
my $codespellfile = "/usr/share/codespell/dictionary.txt";
my $user_codespellfile = "";
my $conststructsfile = "$D/const_structs.checkpatch";
my $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst";
my $typedefsfile;
my $color = "auto";
my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
@ -80,6 +84,7 @@ Version: $V
Options:
-q, --quiet quiet
-v, --verbose verbose mode
--no-tree run without a kernel tree
--no-signoff do not check for 'Signed-off-by' line
--patch treat FILE as patchfile (default)
@ -160,15 +165,51 @@ sub list_types {
my $text = <$script>;
close($script);
my @types = ();
my %types = ();
# Also catch when type or level is passed through a variable
for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
push (@types, $_);
while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
if (defined($1)) {
if (exists($types{$2})) {
$types{$2} .= ",$1" if ($types{$2} ne $1);
} else {
$types{$2} = $1;
}
} else {
$types{$2} = "UNDETERMINED";
}
}
@types = sort(uniq(@types));
print("#\tMessage type\n\n");
foreach my $type (@types) {
if ($color) {
print(" ( Color coding: ");
print(RED . "ERROR" . RESET);
print(" | ");
print(YELLOW . "WARNING" . RESET);
print(" | ");
print(GREEN . "CHECK" . RESET);
print(" | ");
print("Multiple levels / Undetermined");
print(" )\n\n");
}
foreach my $type (sort keys %types) {
my $orig_type = $type;
if ($color) {
my $level = $types{$type};
if ($level eq "ERROR") {
$type = RED . $type . RESET;
} elsif ($level eq "WARN") {
$type = YELLOW . $type . RESET;
} elsif ($level eq "CHK") {
$type = GREEN . $type . RESET;
}
}
print(++$count . "\t" . $type . "\n");
if ($verbose && exists($verbose_messages{$orig_type})) {
my $message = $verbose_messages{$orig_type};
$message =~ s/\n/\n\t/g;
print("\t" . $message . "\n\n");
}
}
exit($exitcode);
@ -200,6 +241,46 @@ if (-f $conf) {
unshift(@ARGV, @conf_args) if @conf_args;
}
sub load_docs {
open(my $docs, '<', "$docsfile")
or warn "$P: Can't read the documentation file $docsfile $!\n";
my $type = '';
my $desc = '';
my $in_desc = 0;
while (<$docs>) {
chomp;
my $line = $_;
$line =~ s/\s+$//;
if ($line =~ /^\s*\*\*(.+)\*\*$/) {
if ($desc ne '') {
$verbose_messages{$type} = trim($desc);
}
$type = $1;
$desc = '';
$in_desc = 1;
} elsif ($in_desc) {
if ($line =~ /^(?:\s{4,}|$)/) {
$line =~ s/^\s{4}//;
$desc .= $line;
$desc .= "\n";
} else {
$verbose_messages{$type} = trim($desc);
$type = '';
$desc = '';
$in_desc = 0;
}
}
}
if ($desc ne '') {
$verbose_messages{$type} = trim($desc);
}
close($docs);
}
# Perl's Getopt::Long allows options to take optional arguments after a space.
# Prevent --color by itself from consuming other arguments
foreach (@ARGV) {
@ -210,6 +291,7 @@ foreach (@ARGV) {
GetOptions(
'q|quiet+' => \$quiet,
'v|verbose!' => \$verbose,
'tree!' => \$tree,
'signoff!' => \$chk_signoff,
'patch!' => \$chk_patch,
@ -272,13 +354,27 @@ EOF
# $help is 2 if invalid option is passed - exitcode: 1
help($help - 1) if ($help);
die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
die "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
if ($color =~ /^[01]$/) {
$color = !$color;
} elsif ($color =~ /^always$/i) {
$color = 1;
} elsif ($color =~ /^never$/i) {
$color = 0;
} elsif ($color =~ /^auto$/i) {
$color = (-t STDOUT);
} else {
die "$P: Invalid color mode: $color\n";
}
load_docs() if ($verbose);
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;
@ -293,18 +389,6 @@ if ($#ARGV < 0) {
push(@ARGV, '-');
}
if ($color =~ /^[01]$/) {
$color = !$color;
} elsif ($color =~ /^always$/i) {
$color = 1;
} elsif ($color =~ /^never$/i) {
$color = 0;
} elsif ($color =~ /^auto$/i) {
$color = (-t STDOUT);
} else {
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);
@ -432,7 +516,8 @@ our $Attribute = qr{
____cacheline_aligned|
____cacheline_aligned_in_smp|
____cacheline_internodealigned_in_smp|
__weak
__weak|
__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\)
}x;
our $Modifier;
our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
@ -444,7 +529,7 @@ our $Binary = qr{(?i)0b[01]+$Int_type?};
our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
our $Int = qr{[0-9]+$Int_type?};
our $Octal = qr{0[0-7]+$Int_type?};
our $String = qr{"[X\t]*"};
our $String = qr{(?:\b[Lu])?"[X\t]*"};
our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
@ -1028,10 +1113,10 @@ sub is_maintained_obsolete {
sub is_SPDX_License_valid {
my ($license) = @_;
return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
my $root_path = abs_path($root);
my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
return 0 if ($status ne "");
return 1;
}
@ -1125,7 +1210,8 @@ sub git_commit_info {
# git log --format='%H %s' -1 $line |
# echo "commit $(cut -c 1-12,41-)"
# done
} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
$lines[0] =~ /^fatal: bad object $commit/) {
$id = undef;
} else {
$id = substr($lines[0], 0, 12);
@ -2245,7 +2331,16 @@ sub report {
splice(@lines, 1, 1);
$output = join("\n", @lines);
}
$output = (split('\n', $output))[0] . "\n" if ($terse);
if ($terse) {
$output = (split('\n', $output))[0] . "\n";
}
if ($verbose && exists($verbose_messages{$type}) &&
!exists($verbose_emitted{$type})) {
$output .= $verbose_messages{$type} . "\n\n";
$verbose_emitted{$type} = 1;
}
push(our @report, $output);
@ -2532,6 +2627,8 @@ sub process {
my $last_abi_file = '';
my $non_utf8_charset = 0;
my $last_git_commit_id_linenr = -1;
my $last_blank_line = 0;
my $last_coalesced_string_linenr = -1;
@ -2864,10 +2961,10 @@ sub process {
my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
if ($email_address eq $author_address && $email_name eq $author_name) {
if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
$author_sob = $ctx;
$authorsignoff = 2;
} elsif ($email_address eq $author_address) {
} elsif (lc $email_address eq lc $author_address) {
$author_sob = $ctx;
$authorsignoff = 3;
} elsif ($email_name eq $author_name) {
@ -3099,7 +3196,7 @@ sub process {
length($line) > 75 &&
!($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
# file delta changes
$line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
$line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
# filename then :
$line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
# A Fixes: or Link: line or signature tag line
@ -3125,10 +3222,20 @@ sub process {
}
# Check for git id commit length and improperly formed commit descriptions
if ($in_commit_log && !$commit_log_possible_stack_dump &&
# A correctly formed commit description is:
# commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
# with the commit subject '("' prefix and '")' suffix
# This is a fairly compilicated block as it tests for what appears to be
# bare SHA-1 hash with minimum length of 5. It also avoids several types of
# possible SHA-1 matches.
# A commit match can span multiple lines so this block attempts to find a
# complete typical commit on a maximum of 3 lines
if ($perl_version_ok &&
$in_commit_log && !$commit_log_possible_stack_dump &&
$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 =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
$line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
$line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
@ -3138,49 +3245,56 @@ sub process {
my $long = 0;
my $case = 1;
my $space = 1;
my $hasdesc = 0;
my $hasparens = 0;
my $id = '0123456789ab';
my $orig_desc = "commit description";
my $description = "";
my $herectx = $herecurr;
my $has_parens = 0;
my $has_quotes = 0;
if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
$init_char = $1;
$orig_commit = lc($2);
} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
$orig_commit = lc($1);
my $input = $line;
if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
for (my $n = 0; $n < 2; $n++) {
if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
$orig_desc = $1;
$has_parens = 1;
# Always strip leading/trailing parens then double quotes if existing
$orig_desc = substr($orig_desc, 1, -1);
if ($orig_desc =~ /^".*"$/) {
$orig_desc = substr($orig_desc, 1, -1);
$has_quotes = 1;
}
last;
}
last if ($#lines < $linenr + $n);
$input .= " " . trim($rawlines[$linenr + $n]);
$herectx .= "$rawlines[$linenr + $n]\n";
}
$herectx = $herecurr if (!$has_parens);
}
$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
$orig_desc = $1;
$hasparens = 1;
} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
defined $rawlines[$linenr] &&
$rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
$orig_desc = $1;
$hasparens = 1;
} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
defined $rawlines[$linenr] &&
$rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
$orig_desc = $1;
$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
$orig_desc .= " " . $1;
$hasparens = 1;
if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
$init_char = $1;
$orig_commit = lc($2);
$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
$orig_commit = lc($1);
}
($id, $description) = git_commit_info($orig_commit,
$id, $orig_desc);
if (defined($id) &&
($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
$last_git_commit_id_linenr != $linenr - 1) {
ERROR("GIT_COMMIT_ID",
"Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
"Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
}
#don't report the next line if this line ends in commit and the sha1 hash is the next line
$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
}
# Check for added, moved or deleted files
@ -3202,7 +3316,7 @@ sub process {
($line =~ /^new file mode\s*\d+\s*$/) &&
($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
WARN("DT_SCHEMA_BINDING_PATCH",
"DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
"DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
}
# Check for wrappage within a valid hunk of the file
@ -3391,47 +3505,47 @@ sub process {
# Kconfig supports named choices), so use a word boundary
# (\b) rather than a whitespace character (\s)
$line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
my $length = 0;
my $cnt = $realcnt;
my $ln = $linenr + 1;
my $f;
my $is_start = 0;
my $is_end = 0;
for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
$f = $lines[$ln - 1];
$cnt-- if ($lines[$ln - 1] !~ /^-/);
$is_end = $lines[$ln - 1] =~ /^\+/;
my $ln = $linenr;
my $needs_help = 0;
my $has_help = 0;
my $help_length = 0;
while (defined $lines[$ln]) {
my $f = $lines[$ln++];
next if ($f =~ /^-/);
last if (!$file && $f =~ /^\@\@/);
last if ($f !~ /^[\+ ]/); # !patch context
if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
$is_start = 1;
} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
$length = -1;
if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
$needs_help = 1;
next;
}
if ($f =~ /^\+\s*help\s*$/) {
$has_help = 1;
next;
}
$f =~ s/^.//;
$f =~ s/#.*//;
$f =~ s/^\s+//;
next if ($f =~ /^$/);
$f =~ s/^.//; # strip patch context [+ ]
$f =~ s/#.*//; # strip # directives
$f =~ s/^\s+//; # strip leading blanks
next if ($f =~ /^$/); # skip blank lines
# At the end of this Kconfig block:
# This only checks context lines in the patch
# and so hopefully shouldn't trigger false
# positives, even though some of these are
# common words in help texts
if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
if|endif|menu|endmenu|source)\b/x) {
$is_end = 1;
if ($f =~ /^(?:config|menuconfig|choice|endchoice|
if|endif|menu|endmenu|source)\b/x) {
last;
}
$length++;
$help_length++ if ($has_help);
}
if ($is_start && $is_end && $length < $min_conf_desc_length) {
if ($needs_help &&
$help_length < $min_conf_desc_length) {
my $stat_real = get_stat_real($linenr, $ln - 1);
WARN("CONFIG_DESCRIPTION",
"please write a paragraph that describes the config symbol fully\n" . $herecurr);
"please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n");
}
#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
}
# check MAINTAINERS entries
@ -4395,6 +4509,7 @@ sub process {
# XXX(foo);
# EXPORT_SYMBOL(something_foo);
my $name = $1;
$name =~ s/^\s*($Ident).*/$1/;
if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
$name =~ /^${Ident}_$2/) {
#print "FOO C name<$name>\n";
@ -5332,9 +5447,13 @@ sub process {
}
}
#goto labels aren't indented, allow a single space however
if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
!($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
# check that goto labels aren't indented (allow a single space indentation)
# and ignore bitfield definitions like foo:1
# Strictly, labels can have whitespace after the identifier and before the :
# but this is not allowed here as many ?: uses would appear to be labels
if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
$sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
$sline !~ /^.\s+default:/) {
if (WARN("INDENTED_LABEL",
"labels should not be indented\n" . $herecurr) &&
$fix) {
@ -5429,7 +5548,7 @@ sub process {
# Return of what appears to be an errno should normally be negative
if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
my $name = $1;
if ($name ne 'EOF' && $name ne 'ERROR') {
if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
WARN("USE_NEGATIVE_ERRNO",
"return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
}
@ -5800,7 +5919,7 @@ sub process {
next if ($arg =~ /\.\.\./);
next if ($arg =~ /^type$/i);
my $tmp_stmt = $define_stmt;
$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
$tmp_stmt =~ s/\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
$tmp_stmt =~ s/\#+\s*$arg\b//g;
$tmp_stmt =~ s/\b$arg\s*\#\#//g;
my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
@ -6100,7 +6219,8 @@ sub process {
}
# concatenated string without spaces between elements
if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
if ($line =~ /$String[A-Z_]/ ||
($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
if (CHK("CONCATENATED_STRING",
"Concatenated strings should use spaces between elements\n" . $herecurr) &&
$fix) {
@ -6113,7 +6233,7 @@ sub process {
}
# uncoalesced string fragments
if ($line =~ /$String\s*"/) {
if ($line =~ /$String\s*[Lu]?"/) {
if (WARN("STRING_FRAGMENTS",
"Consecutive strings are generally better as a single string\n" . $herecurr) &&
$fix) {
@ -6686,9 +6806,11 @@ sub process {
$specifier = $1;
$extension = $2;
$qualifier = $3;
if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
($extension eq "f" &&
defined $qualifier && $qualifier !~ /^w/)) {
defined $qualifier && $qualifier !~ /^w/) ||
($extension eq "4" &&
defined $qualifier && $qualifier !~ /^cc/)) {
$bad_specifier = $specifier;
last;
}
@ -6991,7 +7113,7 @@ sub process {
}
# check for alloc argument mismatch
if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) {
WARN("ALLOC_ARRAY_ARGS",
"$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
}
@ -7183,6 +7305,17 @@ sub process {
"Using $1 should generally have parentheses around the comparison\n" . $herecurr);
}
# return sysfs_emit(foo, fmt, ...) fmt without newline
if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
my $offset = $+[6] - 1;
if (WARN("SYSFS_EMIT",
"return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
$fix) {
substr($fixed[$fixlinenr], $offset, 0) = '\\n';
}
}
# nested likely/unlikely calls
if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
WARN("LIKELY_MISUSE",