7976 lines · 239.6 KB · Perl
RawDownload
				my $func = $1;				if (WARN('NEEDLESS_IF',					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&				    $fix) {					my $do_fix = 1;					my $leading_tabs = "";					my $new_leading_tabs = "";					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {						$leading_tabs = $1;					} else {						$do_fix = 0;					}					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {						$new_leading_tabs = $1;						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {							$do_fix = 0;						}					} else {						$do_fix = 0;					}					if ($do_fix) {						fix_delete_line($fixlinenr - 1, $prevrawline);						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;					}				}			}		} # check for unnecessary "Out of Memory" messages		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&		    (defined $1 || defined $3) &&		    $linenr > 3) {			my $testval = $2;			my $testline = $lines[$linenr - 3]; 			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&			    $s !~ /\b__GFP_NOWARN\b/ ) {				WARN("OOM_MESSAGE",				     "Possible unnecessary 'out of memory' message\n" . $hereprev);			}		} # check for logging functions with KERN_<LEVEL>		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {			my $level = $1;			if (WARN("UNNECESSARY_KERN_LEVEL",				 "Possible unnecessary $level\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\s*$level\s*//;			}		} # check for logging continuations		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {			WARN("LOGGING_CONTINUATION",			     "Avoid logging continuation uses where feasible\n" . $herecurr);		} # check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions		if (defined $stat &&		    $line =~ /\b$logFunctions\s*\(/ &&		    index($stat, '"') >= 0) {			my $lc = $stat =~ tr@\n@@;			$lc = $lc + $linenr;			my $stat_real = get_stat_real($linenr, $lc);			pos($stat_real) = index($stat_real, '"');			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {				my $pspec = $1;				my $h = $2;				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;				if (WARN("UNNECESSARY_MODIFIER",					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {					my $nspec = $pspec;					$nspec =~ s/h//g;					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;				}			}		} # check for mask then right shift without a parentheses		if ($perl_version_ok &&		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so			WARN("MASK_THEN_SHIFT",			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);		} # check for pointer comparisons to NULL		if ($perl_version_ok) {			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {				my $val = $1;				my $equal = "!";				$equal = "" if ($4 eq "!=");				if (CHK("COMPARISON_TO_NULL",					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&					    $fix) {					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;				}			}		} # check for bad placement of section $InitAttribute (e.g.: __initdata)		if ($line =~ /(\b$InitAttribute\b)/) {			my $attr = $1;			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {				my $ptr = $1;				my $var = $2;				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&				      ERROR("MISPLACED_INIT",					    "$attr should be placed after $var\n" . $herecurr)) ||				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&				      WARN("MISPLACED_INIT",					   "$attr should be placed after $var\n" . $herecurr))) &&				    $fix) {					$fixed[$fixlinenr] =~ 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;				}			}		} # check for $InitAttributeData (ie: __initdata) with const		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {			my $attr = $1;			$attr =~ /($InitAttributePrefix)(.*)/;			my $attr_prefix = $1;			my $attr_type = $2;			if (ERROR("INIT_ATTRIBUTE",				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~				    s/$InitAttributeData/${attr_prefix}initconst/;			}		} # check for $InitAttributeConst (ie: __initconst) without const		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {			my $attr = $1;			if (ERROR("INIT_ATTRIBUTE",				  "Use of $attr requires a separate use of const\n" . $herecurr) &&			    $fix) {				my $lead = $fixed[$fixlinenr] =~				    /(^\+\s*(?:static\s+))/;				$lead = rtrim($1);				$lead = "$lead " if ($lead !~ /^\+$/);				$lead = "${lead}const ";				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;			}		} # check for __read_mostly with const non-pointer (should just be const)		if ($line =~ /\b__read_mostly\b/ &&		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {			if (ERROR("CONST_READ_MOSTLY",				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;			}		} # don't use __constant_<foo> functions outside of include/uapi/		if ($realfile !~ m@^include/uapi/@ &&		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {			my $constant_func = $1;			my $func = $constant_func;			$func =~ s/^__constant_//;			if (WARN("CONSTANT_CONVERSION",				 "$constant_func should be $func\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;			}		} # prefer usleep_range over udelay		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {			my $delay = $1;			# ignore udelay's < 10, however			if (! ($delay < 10) ) {				CHK("USLEEP_RANGE",				    "usleep_range is preferred over udelay; see function description of usleep_range() and udelay().\n" . $herecurr);			}			if ($delay > 2000) {				WARN("LONG_UDELAY",				     "long udelay - prefer mdelay; see function description of mdelay().\n" . $herecurr);			}		} # warn about unexpectedly long msleep's		if ($line =~ /\bmsleep\s*\((\d+)\);/) {			if ($1 < 20) {				WARN("MSLEEP",				     "msleep < 20ms can sleep for up to 20ms; see function description of msleep().\n" . $herecurr);			}		} # check for comparisons of jiffies		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {			WARN("JIFFIES_COMPARISON",			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);		} # check for comparisons of get_jiffies_64()		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {			WARN("JIFFIES_COMPARISON",			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);		} # warn about #ifdefs in C files#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {#			print "#ifdef in C files should be avoided\n";#			print "$herecurr";#			$clean = 0;#		} # warn about spacing in #ifdefs		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {			if (ERROR("SPACING",				  "exactly one space required after that #$1\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;			} 		} # check for spinlock_t definitions without a comment.		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {			my $which = $1;			if (!ctx_has_comment($first_line, $linenr)) {				CHK("UNCOMMENTED_DEFINITION",				    "$1 definition without comment\n" . $herecurr);			}		}# check for memory barriers without a comment. 		my $barriers = qr{			mb|			rmb|			wmb		}x;		my $barrier_stems = qr{			mb__before_atomic|			mb__after_atomic|			store_release|			load_acquire|			store_mb|			(?:$barriers)		}x;		my $all_barriers = qr{			(?:$barriers)|			smp_(?:$barrier_stems)|			virt_(?:$barrier_stems)		}x; 		if ($line =~ /\b(?:$all_barriers)\s*\(/) {			if (!ctx_has_comment($first_line, $linenr)) {				WARN("MEMORY_BARRIER",				     "memory barrier without comment\n" . $herecurr);			}		} 		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 		if ($realfile !~ m@^include/asm-generic/@ &&		    $realfile !~ m@/barrier\.h$@ &&		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {			WARN("MEMORY_BARRIER",			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);		} # check for waitqueue_active without a comment.		if ($line =~ /\bwaitqueue_active\s*\(/) {			if (!ctx_has_comment($first_line, $linenr)) {				WARN("WAITQUEUE_ACTIVE",				     "waitqueue_active without comment\n" . $herecurr);			}		} # check for data_race without a comment.		if ($line =~ /\bdata_race\s*\(/) {			if (!ctx_has_comment($first_line, $linenr)) {				WARN("DATA_RACE",				     "data_race without comment\n" . $herecurr);			}		} # check for context_unsafe without a comment.		if ($line =~ /\bcontext_unsafe\b/ &&		    !ctx_has_comment($first_line, $linenr)) {			WARN("CONTEXT_UNSAFE",			     "context_unsafe without comment\n" . $herecurr);		} # check of hardware specific defines		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {			CHK("ARCH_DEFINES",			    "architecture specific defines should be avoided\n" .  $herecurr);		} # check that the storage class is not after a type		if ($line =~ /\b($Type)\s+($Storage)\b/) {			WARN("STORAGE_CLASS",			     "storage class '$2' should be located before type '$1'\n" . $herecurr);		}# Check that the storage class is at the beginning of a declaration		if ($line =~ /\b$Storage\b/ &&		    $line !~ /^.\s*$Storage/ &&		    $line =~ /^.\s*(.+?)\$Storage\s/ &&		    $1 !~ /[\,\)]\s*$/) {			WARN("STORAGE_CLASS",			     "storage class should be at the beginning of the declaration\n" . $herecurr);		} # check the location of the inline attribute, that it is between# storage class and type.		if ($line =~ /\b$Type\s+$Inline\b/ ||		    $line =~ /\b$Inline\s+$Storage\b/) {			ERROR("INLINE_LOCATION",			      "inline keyword should sit between storage class and type\n" . $herecurr);		} # Check for __inline__ and __inline, prefer inline		if ($realfile !~ m@\binclude/uapi/@ &&		    $line =~ /\b(__inline__|__inline)\b/) {			if (WARN("INLINE",				 "plain inline is preferred over $1\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 			}		} # Check for compiler attributes		if ($realfile !~ m@\binclude/uapi/@ &&		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {			my $attr = $1;			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/; 			my %attr_list = (				"alias"				=> "__alias",				"aligned"			=> "__aligned",				"always_inline"			=> "__always_inline",				"assume_aligned"		=> "__assume_aligned",				"cold"				=> "__cold",				"const"				=> "__attribute_const__",				"copy"				=> "__copy",				"designated_init"		=> "__designated_init",				"externally_visible"		=> "__visible",				"format"			=> "printf|scanf",				"gnu_inline"			=> "__gnu_inline",				"malloc"			=> "__malloc",				"mode"				=> "__mode",				"no_caller_saved_registers"	=> "__no_caller_saved_registers",				"noclone"			=> "__noclone",				"noinline"			=> "noinline",				"nonstring"			=> "__nonstring",				"noreturn"			=> "__noreturn",				"packed"			=> "__packed",				"pure"				=> "__pure",				"section"			=> "__section",				"used"				=> "__used",				"weak"				=> "__weak"			); 			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {				my $orig_attr = $1;				my $params = '';				$params = $2 if defined($2);				my $curr_attr = $orig_attr;				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;				if (exists($attr_list{$curr_attr})) {					my $new = $attr_list{$curr_attr};					if ($curr_attr eq "format" && $params) {						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;						$new = "__$1\($2";					} else {						$new = "$new$params";					}					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&					    $fix) {						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';						$fixed[$fixlinenr] =~ s/$remove//;						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;					}				}			} 			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused			if ($attr =~ /^_*unused/) {				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);			}		} # Check for __attribute__ weak, or __weak declarations (may have link issues)		if ($perl_version_ok &&		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||		     $line =~ /\b__weak\b/)) {			ERROR("WEAK_DECLARATION",			      "Using weak declarations can have unintended link defects\n" . $herecurr);		} # check for c99 types like uint8_t used outside of uapi/ and tools/		if ($realfile !~ m@\binclude/uapi/@ &&		    $realfile !~ m@\btools/@ &&		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {			my $type = $1;			if ($type =~ /\b($typeC99Typedefs)\b/) {				$type = $1;				my $kernel_type = 'u';				$kernel_type = 's' if ($type =~ /^_*[si]/);				$type =~ /(\d+)/;				$kernel_type .= $1;				if (CHK("PREFER_KERNEL_TYPES",					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;				}			}		} # check for cast of C90 native int or longer types constants		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {			my $cast = $1;			my $const = $2;			my $suffix = "";			my $newconst = $const;			$newconst =~ s/${Int_type}$//;			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);			if ($cast =~ /\blong\s+long\b/) {			    $suffix .= 'LL';			} elsif ($cast =~ /\blong\b/) {			    $suffix .= 'L';			}			if (WARN("TYPECAST_INT_CONSTANT",				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;			}		} # check for sizeof(&)		if ($line =~ /\bsizeof\s*\(\s*\&/) {			WARN("SIZEOF_ADDRESS",			     "sizeof(& should be avoided\n" . $herecurr);		} # check for sizeof without parenthesis		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {			if (WARN("SIZEOF_PARENTHESIS",				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;			}		} # check for struct spinlock declarations		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {			WARN("USE_SPINLOCK_T",			     "struct spinlock should be spinlock_t\n" . $herecurr);		} # check for seq_printf uses that could be seq_puts		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {			my $fmt = get_quoted_string($line, $rawline);			$fmt =~ s/%%//g;			if ($fmt !~ /%/) {				if (WARN("PREFER_SEQ_PUTS",					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;				}			}		} # check for vsprintf extension %p<foo> misuses		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&		    $1 !~ /^_*volatile_*$/) {			my $stat_real; 			my $lc = $stat =~ tr@\n@@;			$lc = $lc + $linenr;		        for (my $count = $linenr; $count <= $lc; $count++) {				my $specifier;				my $extension;				my $qualifier;				my $bad_specifier = "";				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));

Lines 6501–7000 of 7976. Previous lines