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
6187 }6187 }
6188 }6188 }
6189 6189
6190# Check for __attribute__ packed, prefer __packed6190# Check for compiler attributes
6191 if ($realfile !~ m@\binclude/uapi/@ &&6191 if ($realfile !~ m@\binclude/uapi/@ &&
6192 $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {6192 $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
6193 WARN("PREFER_PACKED",6193 my $attr = $1;
6194 "__packed is preferred over __attribute__((packed))\n" . $herecurr);6194 $attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
6195 }6195
6196 6196 my %attr_list = (
6197# Check for __attribute__ aligned, prefer __aligned6197 "aligned" => "__aligned",
6198 if ($realfile !~ m@\binclude/uapi/@ &&6198 "always_inline" => "__always_inline",
6199 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {6199 "assume_aligned" => "__assume_aligned",
6200 WARN("PREFER_ALIGNED",6200 "cold" => "__cold",
6201 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);6201 "const" => "__attribute_const__",
6202 }6202 "copy" => "__copy",
6203 6203 "designated_init" => "__designated_init",
6204# Check for __attribute__ section, prefer __section6204 "externally_visible" => "__visible",
6205 if ($realfile !~ m@\binclude/uapi/@ &&6205 "format" => "printf|scanf",
6206 $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {6206 "gnu_inline" => "__gnu_inline",
6207 my $old = substr($rawline, $-[1], $+[1] - $-[1]);6207 "malloc" => "__malloc",
6208 my $new = substr($old, 1, -1);6208 "mode" => "__mode",
6209 if (WARN("PREFER_SECTION",6209 "no_caller_saved_registers" => "__no_caller_saved_registers",
6210 "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&6210 "noclone" => "__noclone",
6211 $fix) {6211 "noinline" => "noinline",
6212 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;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 }
6213 }6240 }
6214 }
6215 6241
6216# Check for __attribute__ format(printf, prefer __printf6242 if (scalar @conv_array > 0 && $conv_possible == 1) {
6217 if ($realfile !~ m@\binclude/uapi/@ &&6243 my $replace = join(' ', @conv_array);
6218 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {6244 if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6219 if (WARN("PREFER_PRINTF",6245 "$replace is preferred over __attribute__(($attr))\n" . $herecurr) &&
6220 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&6246 $fix) {
6221 $fix) {6247 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*\Q$attr\E\s*\)\s*\)/$replace/;
6222 $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;6248 $fixed[$fixlinenr] =~ s/\}\Q$replace\E/} $replace/;
6249 }
6250 }
6223 6251
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 }
6224 }6261 }
6225 }
6226 6262
6227# Check for __attribute__ format(scanf, prefer __scanf6263 # Check for __attribute__ unused, prefer __always_unused or __maybe_unused
6228 if ($realfile !~ m@\binclude/uapi/@ &&6264 if ($attr =~ /^_*unused/) {
6229 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {6265 WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6230 if (WARN("PREFER_SCANF",6266 "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
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;
6234 }6267 }
6235 }6268 }
6236 6269