aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorJoe Perches <joe@perches.com>2013-09-11 17:24:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-11 18:58:49 -0400
commit8716de383b82f16d920513138f1691e40ef5a9e3 (patch)
tree2709bb597a4d722eb1777aea752aad62c843ba04 /scripts
parent58cb3cf66cc6330910316abb1dc7a7aa78917a27 (diff)
checkpatch: add test for positional misuse of section specifiers like __initdata
As discussed recently on the arm [1] and lm-sensors [2] lists, it is possible to use section markers on variables in a way which gcc doesn't understand (or at least not the way the developer intended): static struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = { does NOT put exynos4_plls in the .initdata section. The __initdata marker can be virtually anywhere on the line, EXCEPT right after "struct". The preferred location is before the "=" sign if there is one, or before the trailing ";" otherwise. [1] http://permalink.gmane.org/gmane.linux.ports.arm.kernel/258149 [2] http://lists.lm-sensors.org/pipermail/lm-sensors/2013-August/039836.html So, update checkpatch to find these misuses and report an error when it's immediately after struct or union, and a warning when it's otherwise not immediately before the ; or =. A similar patch was suggested by Andi Kleen https://lkml.org/lkml/2013/8/5/648 Signed-off-by: Joe Perches <joe@perches.com> Suggested-by: Jean Delvare <khali@linux-fr.org> Tested-by: Guenter Roeck <linux@roeck-us.net> Cc: Andi Kleen <andi@firstfloor.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/checkpatch.pl47
1 files changed, 46 insertions, 1 deletions
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 9ba4fc44112a..47016c304c84 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -242,6 +242,8 @@ our $Sparse = qr{
242 __rcu 242 __rcu
243 }x; 243 }x;
244 244
245our $InitAttribute = qr{__(?:mem|cpu|dev|net_|)(?:initdata|initconst|init\b)};
246
245# Notes to $Attribute: 247# Notes to $Attribute:
246# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 248# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
247our $Attribute = qr{ 249our $Attribute = qr{
@@ -262,7 +264,7 @@ our $Attribute = qr{
262 __deprecated| 264 __deprecated|
263 __read_mostly| 265 __read_mostly|
264 __kprobes| 266 __kprobes|
265 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| 267 $InitAttribute|
266 ____cacheline_aligned| 268 ____cacheline_aligned|
267 ____cacheline_aligned_in_smp| 269 ____cacheline_aligned_in_smp|
268 ____cacheline_internodealigned_in_smp| 270 ____cacheline_internodealigned_in_smp|
@@ -292,6 +294,7 @@ our $Operators = qr{
292 }x; 294 }x;
293 295
294our $NonptrType; 296our $NonptrType;
297our $NonptrTypeWithAttr;
295our $Type; 298our $Type;
296our $Declare; 299our $Declare;
297 300
@@ -354,6 +357,12 @@ our @typeList = (
354 qr{${Ident}_handler}, 357 qr{${Ident}_handler},
355 qr{${Ident}_handler_fn}, 358 qr{${Ident}_handler_fn},
356); 359);
360our @typeListWithAttr = (
361 @typeList,
362 qr{struct\s+$InitAttribute\s+$Ident},
363 qr{union\s+$InitAttribute\s+$Ident},
364);
365
357our @modifierList = ( 366our @modifierList = (
358 qr{fastcall}, 367 qr{fastcall},
359); 368);
@@ -367,6 +376,7 @@ our $allowed_asm_includes = qr{(?x:
367sub build_types { 376sub build_types {
368 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; 377 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
369 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; 378 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
379 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
370 $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 380 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
371 $NonptrType = qr{ 381 $NonptrType = qr{
372 (?:$Modifier\s+|const\s+)* 382 (?:$Modifier\s+|const\s+)*
@@ -377,6 +387,15 @@ sub build_types {
377 ) 387 )
378 (?:\s+$Modifier|\s+const)* 388 (?:\s+$Modifier|\s+const)*
379 }x; 389 }x;
390 $NonptrTypeWithAttr = qr{
391 (?:$Modifier\s+|const\s+)*
392 (?:
393 (?:typeof|__typeof__)\s*\([^\)]*\)|
394 (?:$typeTypedefs\b)|
395 (?:${allWithAttr}\b)
396 )
397 (?:\s+$Modifier|\s+const)*
398 }x;
380 $Type = qr{ 399 $Type = qr{
381 $NonptrType 400 $NonptrType
382 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)? 401 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
@@ -3706,6 +3725,32 @@ sub process {
3706 } 3725 }
3707 } 3726 }
3708 3727
3728sub string_find_replace {
3729 my ($string, $find, $replace) = @_;
3730
3731 $string =~ s/$find/$replace/g;
3732
3733 return $string;
3734}
3735
3736# check for bad placement of section $InitAttribute (e.g.: __initdata)
3737 if ($line =~ /(\b$InitAttribute\b)/) {
3738 my $attr = $1;
3739 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
3740 my $ptr = $1;
3741 my $var = $2;
3742 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
3743 ERROR("MISPLACED_INIT",
3744 "$attr should be placed after $var\n" . $herecurr)) ||
3745 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
3746 WARN("MISPLACED_INIT",
3747 "$attr should be placed after $var\n" . $herecurr))) &&
3748 $fix) {
3749 $fixed[$linenr - 1] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
3750 }
3751 }
3752 }
3753
3709# prefer usleep_range over udelay 3754# prefer usleep_range over udelay
3710 if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 3755 if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
3711 # ignore udelay's < 10, however 3756 # ignore udelay's < 10, however