History

checkpatch: extend attributes check to handle more patterns

It is generally preferred that the macros from include/linux/compiler_attributes.h are used, unless there is a reason not to. checkpatch currently checks __attribute__ for each of packed, aligned, section, printf, scanf, and weak. Other declarations in compiler_attributes.h are not handled. Add a generic test to check the presence of such attributes. Some attributes require more specific handling and are kept separate. Also add fixes to the generic attributes check to substitute the correct conversions. New attributes which are now handled are: __always_inline__ __assume_aligned__(a, ## __VA_ARGS__) __cold__ __const__ __copy__(symbol) __designated_init__ __externally_visible__ __gnu_inline__ __malloc__ __mode__(x) __no_caller_saved_registers__ __noclone__ __noinline__ __nonstring__ __noreturn__ __pure__ __unused__ __used__ Declarations which contain multiple attributes like __attribute__((__packed__, __cold__)) are also handled except when proper conversions for one or more attributes of the list cannot be determined.

Dwaipayan Ray committed 5 years ago

Commit 7ebe1d11 parent dc58bc51 file · +71 −38Browse files

Showing the changes to scripts/checkpatch.pl (1 of 1 file). Show all

Unified · Split

scripts/checkpatch.pl+71−38
@@ -6187,50 +6187,83 @@ sub process { · 6186 unmodified lines
61876187 }
61886188 }
61896189
6190−# Check for __attribute__ packed, prefer __packed
6190+# Check for compiler attributes
61916191 if ($realfile !~ m@\binclude/uapi/@ &&
6192− $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
6193− WARN("PREFER_PACKED",
6194− "__packed is preferred over __attribute__((packed))\n" . $herecurr);
6195− }
6196−
6197−# Check for __attribute__ aligned, prefer __aligned
6198− if ($realfile !~ m@\binclude/uapi/@ &&
6199− $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
6200− WARN("PREFER_ALIGNED",
6201− "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
6202− }
6203−
6204−# Check for __attribute__ section, prefer __section
6205− if ($realfile !~ m@\binclude/uapi/@ &&
6206− $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
6207− my $old = substr($rawline, $-[1], $+[1] - $-[1]);
6208− my $new = substr($old, 1, -1);
6209− if (WARN("PREFER_SECTION",
6210− "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
6211− $fix) {
6212− $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
6192+ $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
6193+ my $attr = $1;
6194+ $attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
6195+
6196+ my %attr_list = (
6197+ "aligned" => "__aligned",
6198+ "always_inline" => "__always_inline",
6199+ "assume_aligned" => "__assume_aligned",
6200+ "cold" => "__cold",
6201+ "const" => "__attribute_const__",
6202+ "copy" => "__copy",
6203+ "designated_init" => "__designated_init",
6204+ "externally_visible" => "__visible",
6205+ "format" => "printf|scanf",
6206+ "gnu_inline" => "__gnu_inline",
6207+ "malloc" => "__malloc",
6208+ "mode" => "__mode",
6209+ "no_caller_saved_registers" => "__no_caller_saved_registers",
6210+ "noclone" => "__noclone",
6211+ "noinline" => "noinline",
6212+ "nonstring" => "__nonstring",
6213+ "noreturn" => "__noreturn",
6214+ "packed" => "__packed",
6215+ "pure" => "__pure",
6216+ "used" => "__used"
6217+ );
6218+
6219+ my @conv_array = ();
6220+ my $conv_possible = 1;
6221+
6222+ while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6223+ my $curr_attr = $1;
6224+ my $params = '';
6225+ $params = $2 if defined($2);
6226+ $curr_attr =~ s/^[\s_]+|[\s_]+$//g;
6227+
6228+ if (exists($attr_list{$curr_attr})) {
6229+ if ($curr_attr eq "format" && $params) {
6230+ $params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6231+ push(@conv_array, "__$1\($2");
6232+ } else {
6233+ my $new = $attr_list{$curr_attr};
6234+ push(@conv_array, "$new$params");
6235+ }
6236+ } else {
6237+ $conv_possible = 0;
6238+ last;
6239+ }
62136240 }
6214− }
62156241
6216−# Check for __attribute__ format(printf, prefer __printf
6217− if ($realfile !~ m@\binclude/uapi/@ &&
6218− $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
6219− if (WARN("PREFER_PRINTF",
6220− "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
6221− $fix) {
6222− $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
6242+ if (scalar @conv_array > 0 && $conv_possible == 1) {
6243+ my $replace = join(' ', @conv_array);
6244+ if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6245+ "$replace is preferred over __attribute__(($attr))\n" . $herecurr) &&
6246+ $fix) {
6247+ $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*\Q$attr\E\s*\)\s*\)/$replace/;
6248+ $fixed[$fixlinenr] =~ s/\}\Q$replace\E/} $replace/;
6249+ }
6250+ }
62236251
6252+ # Check for __attribute__ section, prefer __section
6253+ if ($attr =~ /^_*section_*\s*\(\s*("[^"]*")/) {
6254+ my $old = substr($attr, $-[1], $+[1] - $-[1]);
6255+ my $new = substr($old, 1, -1);
6256+ if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6257+ "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
6258+ $fix) {
6259+ $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
6260+ }
62246261 }
6225− }
62266262
6227−# Check for __attribute__ format(scanf, prefer __scanf
6228− if ($realfile !~ m@\binclude/uapi/@ &&
6229− $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
6230− if (WARN("PREFER_SCANF",
6231− "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
6232− $fix) {
6233− $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
6263+ # Check for __attribute__ unused, prefer __always_unused or __maybe_unused
6264+ if ($attr =~ /^_*unused/) {
6265+ WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6266+ "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
62346267 }
62356268 }
62366269