Skip to content

Commit

Permalink
checkpatch: Support __initconst combined with struct definition
Browse files Browse the repository at this point in the history
Checkpatch sometimes report a false positive for __initconst. E.g., for the
following snippet:

 | static const struct strspn_test {
 | 	const char str[16];
 | 	const char accept[16];
 | 	const char reject[16];
 | 	unsigned a;
 | 	unsigned r;
 | } tests[] __initconst = {
 | 	{ "foobar", "", "", 0, 6 },
 | 	{ "abba", "abc", "ABBA", 4, 4 },
 | 	{ "abba", "a", "b", 1, 1 },
 | 	{ "", "abc", "abc", 0, 0},
 | };

checkpatch would report:

 | ERROR: Use of __initconst requires a separate use of const
 | torvalds#190: FILE: ./test_string.c:190:
 | +	} tests[] __initconst = {

Improve the reporting by trying harder to find the 'const'.

Signed-off-by: Björn Töpel <[email protected]>
  • Loading branch information
bjorn-rivos authored and intel-lab-lkp committed Mar 1, 2023
1 parent c0927a7 commit 42e27a9
Showing 1 changed file with 53 additions and 1 deletion.
54 changes: 53 additions & 1 deletion scripts/checkpatch.pl
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,48 @@ sub ctx_statement_full {
return ($level, $linenr, @chunks);
}

sub ctx_block_outer_rev {
my ($linenr, $open, $close) = @_;
my $line;
my $start = $linenr;
my $blk = '';
my @res = ();

my $level = 0;
my @stack = ($level);
for ($line = $start; $line >= 0; $line--) {
next if ($rawlines[$line] =~ /^-/);

$blk .= $rawlines[$line];

# Handle nested #if/#else.
if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
$level = pop(@stack);
} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
$level = $stack[$#stack - 1];
} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
push(@stack, $level);
}

foreach my $c (split(//, $lines[$line])) {
if ($c eq $close && $level > 0) {
$level--;
last if ($level == 0);
} elsif ($c eq $open) {
$level++;
}
}

if ($level <= 1) {
push(@res, $rawlines[$line]);
}

last if ($level == 0);
}

return @res;
}

sub ctx_block_get {
my ($linenr, $remain, $outer, $open, $close, $off) = @_;
my $line;
Expand Down Expand Up @@ -6502,7 +6544,17 @@ sub process {
# check for $InitAttributeConst (ie: __initconst) without const
if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
my $attr = $1;
if (ERROR("INIT_ATTRIBUTE",
my $error = 1;
if ($line =~ /}/) {
# The const might be part of a struct definition. Try to find that...
my @ctx = ctx_block_outer_rev($linenr, '}', '{');
if (@ctx) {
if ($ctx[$#ctx] =~ /\bconst\b/) {
$error = 0;
}
}
}
if ($error && ERROR("INIT_ATTRIBUTE",
"Use of $attr requires a separate use of const\n" . $herecurr) &&
$fix) {
my $lead = $fixed[$fixlinenr] =~
Expand Down

0 comments on commit 42e27a9

Please sign in to comment.