[cfe-commits] r115123 - /cfe/trunk/tools/scan-build/scan-build
Tom Care
tcare at apple.com
Wed Sep 29 18:12:05 PDT 2010
Author: tcare
Date: Wed Sep 29 20:12:05 2010
New Revision: 115123
URL: http://llvm.org/viewvc/llvm-project?rev=115123&view=rev
Log:
Updated scan-build:
- Idempotent operations are on by default, to match --analyze in the driver.
- Integrated stats calculation based on parsing warnings emitted with the -analyzer-stats flag. The new -stats flag enables this.
- New -maxloop flag to pass down a maxloop value to the analyzer.
Modified:
cfe/trunk/tools/scan-build/scan-build
Modified: cfe/trunk/tools/scan-build/scan-build
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build/scan-build?rev=115123&r1=115122&r2=115123&view=diff
==============================================================================
--- cfe/trunk/tools/scan-build/scan-build (original)
+++ cfe/trunk/tools/scan-build/scan-build Wed Sep 29 20:12:05 2010
@@ -120,7 +120,8 @@
# Do not enable the missing -dealloc check by default.
# '-analyzer-check-objc-missing-dealloc' => 1,
'-analyzer-check-objc-unused-ivars' => 1,
- '-analyzer-check-security-syntactic' => 1
+ '-analyzer-check-security-syntactic' => 1,
+ '-analyzer-check-idempotent-operations' => 1
);
##----------------------------------------------------------------------------##
@@ -304,6 +305,38 @@
}
##----------------------------------------------------------------------------##
+# AddStatLine - Decode and insert a statistics line into the database.
+##----------------------------------------------------------------------------##
+
+sub AddStatLine {
+ my $Line = shift;
+ my $Stats = shift;
+
+ print $Line . "\n";
+
+ my $Regex = qr/(.*?)\ :\ (.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable
+ \ CFGBlocks:\ (\d+)\ \|\ Aborted\ Block:\ (yes|no)\ \|\ Empty\ WorkList:
+ \ (yes|no)/x;
+
+ if ($Line !~ $Regex) {
+ return;
+ }
+
+ # Create a hash of the interesting fields
+ my $Row = {
+ Filename => $1,
+ Function => $2,
+ Total => $3,
+ Unreachable => $4,
+ Aborted => $5,
+ Empty => $6
+ };
+
+ # Add them to the stats array
+ push @$Stats, $Row;
+}
+
+##----------------------------------------------------------------------------##
# ScanFile - Scan a report file for various identifying attributes.
##----------------------------------------------------------------------------##
@@ -317,6 +350,7 @@
my $Index = shift;
my $Dir = shift;
my $FName = shift;
+ my $Stats = shift;
# Compute a digest for the report file. Determine if we have already
# scanned a file that looks just like it.
@@ -337,11 +371,12 @@
# Scan the report file for tags.
open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n");
- my $BugType = "";
- my $BugFile = "";
- my $BugCategory;
- my $BugPathLength = 1;
- my $BugLine = 0;
+ my $BugType = "";
+ my $BugFile = "";
+ my $BugCategory = "";
+ my $BugDescription = "";
+ my $BugPathLength = 1;
+ my $BugLine = 0;
while (<IN>) {
last if (/<!-- BUGMETAEND -->/);
@@ -362,6 +397,9 @@
elsif (/<!-- BUGCATEGORY (.*) -->$/) {
$BugCategory = $1;
}
+ elsif (/<!-- BUGDESC (.*) -->$/) {
+ $BugDescription = $1;
+ }
}
close(IN);
@@ -369,7 +407,13 @@
if (!defined $BugCategory) {
$BugCategory = "Other";
}
-
+
+ # Don't add internal statistics to the bug reports
+ if ($BugCategory =~ /statistics/i) {
+ AddStatLine($BugDescription, $Stats);
+ return;
+ }
+
push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine,
$BugPathLength ];
}
@@ -404,13 +448,61 @@
}
##----------------------------------------------------------------------------##
+# CalcStats - Calculates visitation statistics and returns the string.
+##----------------------------------------------------------------------------##
+
+sub CalcStats {
+ my $Stats = shift;
+
+ my $TotalBlocks = 0;
+ my $UnreachedBlocks = 0;
+ my $TotalFunctions = scalar(@$Stats);
+ my $BlockAborted = 0;
+ my $WorkListAborted = 0;
+ my $Aborted = 0;
+
+ # Calculate the unique files
+ my $FilesHash = {};
+
+ foreach my $Row (@$Stats) {
+ $FilesHash->{$Row->{Filename}} = 1;
+ $TotalBlocks += $Row->{Total};
+ $UnreachedBlocks += $Row->{Unreachable};
+ $BlockAborted++ if $Row->{Aborted} eq 'yes';
+ $WorkListAborted++ if $Row->{Empty} eq 'no';
+ $Aborted++ if $Row->{Aborted} eq 'yes' || $Row->{Empty} eq 'no';
+ }
+
+ my $TotalFiles = scalar(keys(%$FilesHash));
+
+ # Calculations
+ my $PercentAborted = sprintf("%.2f", $Aborted / $TotalFunctions * 100);
+ my $PercentBlockAborted = sprintf("%.2f", $BlockAborted / $TotalFunctions
+ * 100);
+ my $PercentWorkListAborted = sprintf("%.2f", $WorkListAborted /
+ $TotalFunctions * 100);
+ my $PercentBlocksUnreached = sprintf("%.2f", $UnreachedBlocks / $TotalBlocks
+ * 100);
+
+ my $StatsString = "Analyzed $TotalBlocks blocks in $TotalFunctions functions"
+ . " in $TotalFiles files\n"
+ . "$Aborted functions aborted early ($PercentAborted%)\n"
+ . "$BlockAborted had aborted blocks ($PercentBlockAborted%)\n"
+ . "$WorkListAborted had unfinished worklists ($PercentWorkListAborted%)\n"
+ . "$UnreachedBlocks blocks were never reached ($PercentBlocksUnreached%)\n";
+
+ return $StatsString;
+}
+
+##----------------------------------------------------------------------------##
# Postprocess - Postprocess the results of an analysis scan.
##----------------------------------------------------------------------------##
sub Postprocess {
- my $Dir = shift;
- my $BaseDir = shift;
+ my $Dir = shift;
+ my $BaseDir = shift;
+ my $AnalyzerStats = shift;
die "No directory specified." if (!defined $Dir);
@@ -430,8 +522,9 @@
}
# Scan each report file and build an index.
- my @Index;
- foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); }
+ my @Index;
+ my @Stats;
+ foreach my $file (@files) { ScanFile(\@Index, $Dir, $file, \@Stats); }
# Scan the failures directory and use the information in the .info files
# to update the common prefix directory.
@@ -745,6 +838,9 @@
system("chmod", "755", $Dir);
if (defined $BaseDir) { system("chmod", "755", $BaseDir); }
+ # Print statistics
+ print CalcStats(\@Stats) if $AnalyzerStats;
+
my $Num = scalar(@Index);
Diag("$Num bugs found.\n");
if ($Num > 0 && -r "$Dir/index.html") {
@@ -930,6 +1026,12 @@
-no-failure-reports - Do not create a 'failures' subdirectory that includes
analyzer crash reports and preprocessed source files.
+ -stats - Generates visitation statistics for the project being analyzed.
+
+ -maxloop N - specifiy the number of times a block can be visited before giving
+ up. Default is 3. Increase for more comprehensive coverage at a
+ cost of speed.
+
AVAILABLE ANALYSES (multiple analyses may be specified):
ENDTEXT
@@ -1004,6 +1106,8 @@
my $StoreModel;
my $ConstraintsModel;
my $OutputFormat = "html";
+my $AnalyzerStats = 0;
+my $MaxLoop = 0;
if (!@ARGV) {
DisplayHelp();
@@ -1156,6 +1260,16 @@
$ENV{"CCC_REPORT_FAILURES"} = 0;
next;
}
+ if ($arg eq "-stats") {
+ shift @ARGV;
+ $AnalyzerStats = 1;
+ next;
+ }
+ if ($arg eq "-maxloop") {
+ shift @ARGV;
+ $MaxLoop = shift @ARGV;
+ next;
+ }
DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
@@ -1220,6 +1334,14 @@
push @AnalysesToRun,"-analyzer-opt-analyze-headers";
}
+if ($AnalyzerStats) {
+ push @AnalysesToRun, '-analyzer-stats';
+}
+
+if ($MaxLoop > 0) {
+ push @AnalysesToRun, '-analyzer-max-loop ' . $MaxLoop;
+}
+
$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ', at AnalysesToRun;
if (defined $StoreModel) {
@@ -1244,7 +1366,7 @@
}
elsif ($OutputFormat =~ /html/) {
# Postprocess the HTML directory.
- my $NumBugs = Postprocess($HtmlDir, $BaseDir);
+ my $NumBugs = Postprocess($HtmlDir, $BaseDir, $AnalyzerStats);
if ($ViewResults and -r "$HtmlDir/index.html") {
Diag "Analysis run complete.\n";
More information about the cfe-commits
mailing list