summaryrefslogtreecommitdiffstats
path: root/tools/scan-build
diff options
context:
space:
mode:
Diffstat (limited to 'tools/scan-build')
-rwxr-xr-xtools/scan-build/ccc-analyzer77
-rwxr-xr-xtools/scan-build/scan-build132
2 files changed, 102 insertions, 107 deletions
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 25b9800..aca411f 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -14,14 +14,38 @@
use strict;
use warnings;
+use FindBin;
use Cwd qw/ getcwd abs_path /;
use File::Temp qw/ tempfile /;
use File::Path qw / mkpath /;
use File::Basename;
use Text::ParseWords;
-my $CC = $ENV{'CCC_CC'};
-if (!defined $CC) { $CC = "gcc"; }
+##===----------------------------------------------------------------------===##
+# Compiler command setup.
+##===----------------------------------------------------------------------===##
+
+my $Compiler;
+my $Clang;
+
+if ($FindBin::Script =~ /c\+\+-analyzer/) {
+ $Compiler = $ENV{'CCC_CXX'};
+ if (!defined $Compiler) { $Compiler = "g++"; }
+
+ $Clang = $ENV{'CLANG_CXX'};
+ if (!defined $Clang) { $Clang = 'clang++'; }
+}
+else {
+ $Compiler = $ENV{'CCC_CC'};
+ if (!defined $Compiler) { $Compiler = "gcc"; }
+
+ $Clang = $ENV{'CLANG'};
+ if (!defined $Clang) { $Clang = 'clang'; }
+}
+
+##===----------------------------------------------------------------------===##
+# Cleanup.
+##===----------------------------------------------------------------------===##
my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};
if (!defined $ReportFailures) { $ReportFailures = 1; }
@@ -53,7 +77,7 @@ my $ParserRejects = "Parser Rejects";
my $AttributeIgnored = "Attribute Ignored";
sub ProcessClangFailure {
- my ($ClangCC, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
+ my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
my $Dir = "$HtmlDir/failures";
mkpath $Dir;
@@ -69,7 +93,7 @@ sub ProcessClangFailure {
my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX",
SUFFIX => GetPPExt($Lang),
DIR => $Dir);
- system $ClangCC, @$Args, "-E", "-o", $PPFile;
+ system $Clang, @$Args, "-E", "-o", $PPFile;
close ($PPH);
# Create the info file.
@@ -79,7 +103,7 @@ sub ProcessClangFailure {
print OUT "@$Args\n";
close OUT;
`uname -a >> $PPFile.info.txt 2>&1`;
- `$CC -v >> $PPFile.info.txt 2>&1`;
+ `$Compiler -v >> $PPFile.info.txt 2>&1`;
system 'mv',$ofile,"$PPFile.stderr.txt";
return (basename $PPFile);
}
@@ -88,10 +112,6 @@ sub ProcessClangFailure {
# Running the analyzer.
##----------------------------------------------------------------------------##
-# Determine what clang executable to use.
-my $Clang = $ENV{'CLANG'};
-if (!defined $Clang) { $Clang = 'clang'; }
-
sub GetCCArgs {
my $Args = shift;
@@ -106,14 +126,14 @@ sub GetCCArgs {
close(TO_PARENT);
my $line;
while (<FROM_CHILD>) {
- next if (!/clang-cc/);
+ next if (!/-cc1/);
$line = $_;
}
waitpid($pid,0);
close(FROM_CHILD);
- die "could not find clang-cc line\n" if (!defined $line);
+ die "could not find clang line\n" if (!defined $line);
# Strip the newline and initial whitspace
chomp $line;
$line =~ s/^\s+//;
@@ -124,19 +144,16 @@ sub GetCCArgs {
$items[$i] =~ s/\"$//;
}
my $cmd = shift @items;
- die "cannot find 'clang-cc' in 'clang' command\n" if (!($cmd =~ /clang-cc/));
+ die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/));
return \@items;
}
sub Analyze {
- my ($ClangCC, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir,
+ my ($Clang, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir,
$file, $Analyses) = @_;
$Args = GetCCArgs($Args);
- # Skip anything related to C++.
- return if ($Lang =~ /c[+][+]/);
-
my $RunAnalyzer = 0;
my $Cmd;
my @CmdArgs;
@@ -152,13 +169,15 @@ sub Analyze {
@CmdArgsSansAnalyses = @CmdArgs;
}
else {
- $Cmd = $ClangCC;
+ $Cmd = $Clang;
+ push @CmdArgs, "-cc1";
push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))';
- push @CmdArgs,@$Args;
+ push @CmdArgs, @$Args;
@CmdArgsSansAnalyses = @CmdArgs;
push @CmdArgs,'-analyze';
push @CmdArgs,"-analyzer-display-progress";
push @CmdArgs,"-analyzer-eagerly-assume";
+ push @CmdArgs,"-analyzer-opt-analyze-nested-blocks";
push @CmdArgs,(split /\s/,$Analyses);
if (defined $ENV{"CCC_EXPERIMENTAL_CHECKS"}) {
@@ -236,13 +255,13 @@ sub Analyze {
# Did the command die because of a signal?
if ($ReportFailures) {
- if ($Result & 127 and $Cmd eq $ClangCC and defined $HtmlDir) {
- ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses,
+ if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) {
+ ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
$HtmlDir, "Crash", $ofile);
}
elsif ($Result) {
if ($IncludeParserRejects && !($file =~/conftest/)) {
- ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses,
+ ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
$HtmlDir, $ParserRejects, $ofile);
}
}
@@ -274,7 +293,7 @@ sub Analyze {
# Add this file to the list of files that contained this attribute.
# Generate a preprocessed file if we haven't already.
if (!(defined $ppfile)) {
- $ppfile = ProcessClangFailure($ClangCC, $Lang, $file,
+ $ppfile = ProcessClangFailure($Clang, $Lang, $file,
\@CmdArgsSansAnalyses,
$HtmlDir, $AttributeIgnored, $ofile);
}
@@ -359,7 +378,9 @@ my %UniqueOptions = (
my %LangsAccepted = (
"objective-c" => 1,
- "c" => 1
+ "c" => 1,
+ "c++" => 1,
+ "objective-c++" => 1
);
##----------------------------------------------------------------------------##
@@ -375,7 +396,7 @@ my $Output;
my %Uniqued;
# Forward arguments to gcc.
-my $Status = system($CC,@ARGV);
+my $Status = system($Compiler,@ARGV);
if ($Status) { exit($Status >> 8); }
# Get the analysis options.
@@ -399,10 +420,6 @@ my $Verbose = 0;
if (defined $ENV{CCC_ANALYZER_VERBOSE}) { $Verbose = 1; }
if (defined $ENV{CCC_ANALYZER_LOG}) { $Verbose = 2; }
-# Determine what clang-cc executable to use.
-my $ClangCC = $ENV{'CLANG_CC'};
-if (!defined $ClangCC) { $ClangCC = 'clang-cc'; }
-
# Get the HTML output directory.
my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
@@ -617,12 +634,12 @@ if ($Action eq 'compile' or $Action eq 'link') {
push @NewArgs, '-arch';
push @NewArgs, $arch;
push @NewArgs, @CmdArgs;
- Analyze($ClangCC, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output,
+ Analyze($Clang, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output,
$Verbose, $HtmlDir, $file, $Analyses);
}
}
else {
- Analyze($ClangCC, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output,
+ Analyze($Clang, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output,
$Verbose, $HtmlDir, $file, $Analyses);
}
}
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index 8d99f07..f978a88 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -26,7 +26,6 @@ my $Verbose = 0; # Verbose output from this script.
my $Prog = "scan-build";
my $BuildName;
my $BuildDate;
-my $CXX; # Leave undefined initially.
my $TERM = $ENV{'TERM'};
my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT
@@ -81,43 +80,26 @@ sub DieDiag {
# Some initial preprocessing of Clang options.
##----------------------------------------------------------------------------##
-# First, look for 'clang-cc' in libexec.
-my $ClangCCSB = Cwd::realpath("$RealBin/libexec/clang-cc");
-# Second, look for 'clang-cc' in the same directory as scan-build.
-if (!defined $ClangCCSB || ! -x $ClangCCSB) {
- $ClangCCSB = Cwd::realpath("$RealBin/clang-cc");
-}
-# Third, look for 'clang-cc' in ../libexec
-if (!defined $ClangCCSB || ! -x $ClangCCSB) {
- $ClangCCSB = Cwd::realpath("$RealBin/../libexec/clang-cc");
-}
-# Finally, default to looking for 'clang-cc' in the path.
-if (!defined $ClangCCSB || ! -x $ClangCCSB) {
- $ClangCCSB = "clang-cc";
-}
-my $ClangCC = $ClangCCSB;
-
-# Now find 'clang'
+# Find 'clang'
my $ClangSB = Cwd::realpath("$RealBin/bin/clang");
+my $ClangCXXSB;
if (!defined $ClangSB || ! -x $ClangSB) {
$ClangSB = Cwd::realpath("$RealBin/clang");
-}
-# Third, look for 'clang' in ../bin
-if (!defined $ClangSB || ! -x $ClangSB) {
- $ClangSB = Cwd::realpath("$RealBin/../bin/clang");
-}
-# Finally, default to looking for 'clang-cc' in the path.
-if (!defined $ClangSB || ! -x $ClangSB) {
- $ClangSB = "clang";
+ if (defined $ClangSB) { $ClangCXXSB = $ClangSB . "++"; }
}
my $Clang = $ClangSB;
-
+my $ClangCXX = $ClangCXXSB;
+# Default to looking for 'clang' in the path.
+if (!defined $Clang || ! -x $Clang) {
+ $Clang = "clang";
+ $ClangCXX = "clang++";
+}
my %AvailableAnalyses;
# Query clang for analysis options.
-open(PIPE, "-|", $ClangCC, "--help") or
- DieDiag("Cannot execute '$ClangCC'\n");
+open(PIPE, "-|", $Clang, "-cc1", "--help") or
+ DieDiag("Cannot execute '$Clang'\n");
my $FoundAnalysis = 0;
@@ -128,17 +110,14 @@ while(<PIPE>) {
}
next;
}
-
if (/^\s\s\s\s([^\s]+)\s(.+)$/) {
next if ($1 =~ /-dump/ or $1 =~ /-view/
- or $1 =~ /-warn-uninit/);
-
+ or $1 =~ /-warn-uninit/);
$AvailableAnalyses{$1} = $2;
next;
}
last;
}
-
close (PIPE);
my %AnalysesDefaultEnabled = (
@@ -156,10 +135,8 @@ my %AnalysesDefaultEnabled = (
##----------------------------------------------------------------------------##
sub GetHTMLRunDir {
-
die "Not enough arguments." if (@_ == 0);
- my $Dir = shift @_;
-
+ my $Dir = shift @_;
my $TmpMode = 0;
if (!defined $Dir) {
if (`uname` =~ /Darwin/) {
@@ -168,8 +145,7 @@ sub GetHTMLRunDir {
}
else {
$Dir = "/tmp";
- }
-
+ }
$TmpMode = 1;
}
@@ -177,42 +153,32 @@ sub GetHTMLRunDir {
while ($Dir =~ /\/$/) { chop $Dir; }
# Get current date and time.
-
- my @CurrentTime = localtime();
-
+ my @CurrentTime = localtime();
my $year = $CurrentTime[5] + 1900;
my $day = $CurrentTime[3];
my $month = $CurrentTime[4] + 1;
-
my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day);
- # Determine the run number.
-
+ # Determine the run number.
my $RunNumber;
- if (-d $Dir) {
-
+ if (-d $Dir) {
if (! -r $Dir) {
DieDiag("directory '$Dir' exists but is not readable.\n");
- }
-
- # Iterate over all files in the specified directory.
-
- my $max = 0;
-
+ }
+ # Iterate over all files in the specified directory.
+ my $max = 0;
opendir(DIR, $Dir);
my @FILES = grep { -d "$Dir/$_" } readdir(DIR);
closedir(DIR);
-
- foreach my $f (@FILES) {
+ foreach my $f (@FILES) {
# Strip the prefix '$Prog-' if we are dumping files to /tmp.
if ($TmpMode) {
next if (!($f =~ /^$Prog-(.+)/));
$f = $1;
}
-
my @x = split/-/, $f;
next if (scalar(@x) != 4);
next if ($x[0] != $year);
@@ -836,14 +802,26 @@ sub RunBuildCommand {
$Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {
if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) {
- $ENV{"CCC_CC"} = $1;
+ $ENV{"CCC_CC"} = $1;
}
shift @$Args;
unshift @$Args, $CCAnalyzer;
}
+ elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or
+ $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or
+ $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or
+ $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) {
+ if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) {
+ $ENV{"CCC_CXX"} = $1;
+ }
+ shift @$Args;
+ unshift @$Args, $CCAnalyzer;
+ }
elsif ($IgnoreErrors) {
if ($Cmd eq "make" or $Cmd eq "gmake") {
+ AddIfNotPresent($Args, "CC=$CCAnalyzer");
+ AddIfNotPresent($Args, "CXX=$CCAnalyzer");
AddIfNotPresent($Args,"-k");
AddIfNotPresent($Args,"-i");
}
@@ -860,6 +838,7 @@ sub RunBuildCommand {
if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {
if (@$Args[$i+1] =~ /^iphonesimulator3/) {
$ENV{"CCC_CC"} = "gcc-4.2";
+ $ENV{"CCC_CXX"} = "g++-4.2";
}
}
}
@@ -874,10 +853,10 @@ sub RunBuildCommand {
# When 'CC' is set, xcodebuild uses it to do all linking, even if we are
# linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
# when linking such files.
- die if (!defined $CXX);
- my $LDPLUSPLUS = `which $CXX`;
- $LDPLUSPLUS =~ s/\015?\012//; # strip newlines
- $ENV{'LDPLUSPLUS'} = $LDPLUSPLUS;
+ if (!defined $ENV{'CCC_CXX'}) {
+ $ENV{'CCC_CXX'} = 'g++';
+ }
+ $ENV{'LDPLUSPLUS'} = $ENV{'CCC_CXX'};
}
return (system(@$Args) >> 8);
@@ -1125,16 +1104,19 @@ while (@ARGV) {
if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
shift @ARGV;
+ my $cxx;
if (!defined $2 || $2 eq "") {
if (!@ARGV) {
DieDiag("'--use-c++' option requires a compiler executable name.\n");
}
- $CXX = shift @ARGV;
+ $cxx = shift @ARGV;
}
else {
- $CXX = $2;
+ $cxx = $2;
}
+
+ $ENV{"CCC_CXX"} = $cxx;
next;
}
@@ -1206,32 +1188,28 @@ $HtmlDir = GetHTMLRunDir($HtmlDir);
# Set the appropriate environment variables.
SetHtmlEnv(\@ARGV, $HtmlDir);
-my $Cmd = Cwd::realpath("$RealBin/libexec/ccc-analyzer");
+my $AbsRealBin = Cwd::realpath($RealBin);
+my $Cmd = "$AbsRealBin/libexec/ccc-analyzer";
+my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer";
+
if (!defined $Cmd || ! -x $Cmd) {
- $Cmd = Cwd::realpath("$RealBin/ccc-analyzer");
+ $Cmd = "$AbsRealBin/ccc-analyzer";
DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd);
}
-
-if (!defined $ClangCCSB || ! -x $ClangCCSB) {
- Diag("'clang-cc' executable not found in '$RealBin/libexec'.\n");
- Diag("Using 'clang-cc' from path.\n");
+if (!defined $CmdCXX || ! -x $CmdCXX) {
+ $CmdCXX = "$AbsRealBin/c++-analyzer";
+ DieDiag("Executable 'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -x $CmdCXX);
}
+
if (!defined $ClangSB || ! -x $ClangSB) {
Diag("'clang' executable not found in '$RealBin/bin'.\n");
Diag("Using 'clang' from path.\n");
}
-if (defined $CXX) {
- $ENV{'CXX'} = $CXX;
-}
-else {
- $CXX = 'g++'; # This variable is used by other parts of scan-build
- # that need to know a default C++ compiler to fall back to.
-}
-
$ENV{'CC'} = $Cmd;
-$ENV{'CLANG_CC'} = $ClangCC;
+$ENV{'CXX'} = $CmdCXX;
$ENV{'CLANG'} = $Clang;
+$ENV{'CLANG_CXX'} = $ClangCXX;
if ($Verbose >= 2) {
$ENV{'CCC_ANALYZER_VERBOSE'} = 1;
OpenPOWER on IntegriCloud