summaryrefslogtreecommitdiffstats
path: root/tools/scan-build
diff options
context:
space:
mode:
Diffstat (limited to 'tools/scan-build')
-rwxr-xr-xtools/scan-build/ccc-analyzer2
-rwxr-xr-xtools/scan-build/scan-build338
-rw-r--r--tools/scan-build/scan-build.115
-rwxr-xr-xtools/scan-build/set-xcode-analyzer22
4 files changed, 230 insertions, 147 deletions
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index c7636f9..8717225 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -346,6 +346,7 @@ my %LinkerOptionMap = (
my %CompilerLinkerOptionMap = (
'-fobjc-arc' => 0,
+ '-fno-objc-arc' => 0,
'-fobjc-abi-version' => 0, # This is really a 1 argument, but always has '='
'-fobjc-legacy-dispatch' => 0,
'-mios-simulator-version-min' => 0, # This really has 1 argument, but always has '='
@@ -353,6 +354,7 @@ my %CompilerLinkerOptionMap = (
'-arch' => 1,
'-m32' => 0,
'-m64' => 0,
+ '-stdlib' => 0, # This is really a 1 argument, but always has '='
'-v' => 0,
'-fpascal-strings' => 0,
'-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '='
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index 65c4893..a13b235 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -93,30 +93,13 @@ if (grep /^--help-checkers$/, @ARGV) {
}
##----------------------------------------------------------------------------##
-# Some initial preprocessing of Clang options.
+# Declaration of Clang options. Populated later.
##----------------------------------------------------------------------------##
-# Find 'clang'
-my $ClangSB = Cwd::realpath("$RealBin/bin/clang");
-if (!defined $ClangSB || ! -x $ClangSB) {
- $ClangSB = Cwd::realpath("$RealBin/clang");
-}
my $Clang;
-if (!defined $ClangSB || ! -x $ClangSB) {
- # Default to looking for 'clang' in the path.
- $Clang = `which clang`;
- chomp $Clang;
- if ($Clang eq "") {
- DieDiag("No 'clang' executable found in path.\n");
- }
-}
-else {
- $Clang = $ClangSB;
-}
-my $ClangCXX = $Clang;
-$ClangCXX =~ s/\-\d+\.\d+$//;
-$ClangCXX .= "++";
-my $ClangVersion = HtmlEscape(`$Clang --version`);
+my $ClangSB;
+my $ClangCXX;
+my $ClangVersion;
##----------------------------------------------------------------------------##
# GetHTMLRunDir - Construct an HTML directory name for the current sub-run.
@@ -1003,74 +986,107 @@ ENDTEXT
print <<ENDTEXT;
OPTIONS:
- -analyze-headers - Also analyze functions in #included files.
+ -analyze-headers
+
+ Also analyze functions in #included files. By default, such functions
+ are skipped unless they are called by functions within the main source file.
- -o - Target directory for HTML report files. Subdirectories
- will be created as needed to represent separate "runs" of
- the analyzer. If this option is not specified, a directory
- is created in /tmp (TMPDIR on Mac OS X) to store the reports.
-
- -h - Display this message.
+ -o <output location>
+
+ Specifies the output directory for analyzer reports. Subdirectories will be
+ created as needed to represent separate "runs" of the analyzer. If this
+ option is not specified, a directory is created in /tmp (TMPDIR on Mac OS X)
+ to store the reports.
+
+ -h
--help
- -k - Add a "keep on going" option to the specified build command.
- --keep-going This option currently supports make and xcodebuild.
- This is a convenience option; one can specify this
- behavior directly using build options.
+ Display this message.
- --html-title [title] - Specify the title used on generated HTML pages.
- --html-title=[title] If not specified, a default title will be used.
+ -k
+ --keep-going
+
+ Add a "keep on going" option to the specified build command. This option
+ currently supports make and xcodebuild. This is a convenience option; one
+ can specify this behavior directly using build options.
- -plist - By default the output of scan-build is a set of HTML files.
- This option outputs the results as a set of .plist files.
-
- -plist-html - By default the output of scan-build is a set of HTML files.
- This option outputs the results as a set of HTML
- and .plist files.
-
- --status-bugs - By default, the exit status of $Prog is the same as the
- executed build command. Specifying this option causes the
- exit status of $Prog to be 1 if it found potential bugs
- and 0 otherwise.
+ --html-title [title]
+ --html-title=[title]
- --use-cc [compiler path] - $Prog attempts to guess the default compiler for
- --use-cc=[compiler path] your C and Objective-C code. Use this option
- to specify an alternate compiler.
+ Specify the title used on generated HTML pages. If not specified, a default
+ title will be used.
- --use-c++ [compiler path] - $Prog attempts to guess the default compiler for
- --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option
- to specify an alternate compiler.
+ -plist
+
+ By default the output of scan-build is a set of HTML files. This option
+ outputs the results as a set of .plist files.
+
+ -plist-html
+
+ By default the output of scan-build is a set of HTML files. This option
+ outputs the results as a set of HTML and .plist files.
+
+ --status-bugs
+
+ By default, the exit status of scan-build is the same as the executed build
+ command. Specifying this option causes the exit status of scan-build to be 1
+ if it found potential bugs and 0 otherwise.
+
+ --use-cc [compiler path]
+ --use-cc=[compiler path]
+
+ scan-build analyzes a project by interposing a "fake compiler", which
+ executes a real compiler for compilation and the static analyzer for analysis.
+ Because of the current implementation of interposition, scan-build does not
+ know what compiler your project normally uses. Instead, it simply overrides
+ the CC environment variable, and guesses your default compiler.
+
+ In the future, this interposition mechanism to be improved, but if you need
+ scan-build to use a specific compiler for *compilation* then you can use
+ this option to specify a path to that compiler.
+
+ --use-c++ [compiler path]
+ --use-c++=[compiler path]
+
+ This is the same as "-use-cc" but for C++ code.
+
+ -v
+
+ Enable verbose output from scan-build. A second and third '-v' increases
+ verbosity.
- -v - Verbose output from $Prog and the analyzer.
- A second and third '-v' increases verbosity.
+ -V
+ --view
- -V - View analysis results in a web browser when the build
- --view completes.
+ View analysis results in a web browser when the build completes.
ADVANCED OPTIONS:
- -constraints [model] - Specify the contraint engine used by the analyzer.
- By default the 'range' model is used. Specifying
- 'basic' uses a simpler, less powerful constraint model
- used by checker-0.160 and earlier.
-
- -store [model] - Specify the store model used by the analyzer. By default,
- the 'region' store model is used. 'region' specifies a field-
- sensitive store model. Users can also specify 'basic', which
- is far less precise but can more quickly analyze code.
- 'basic' was the default store model for checker-0.221 and
- earlier.
-
- -no-failure-reports - Do not create a 'failures' subdirectory that includes
- analyzer crash reports and preprocessed source files.
+ -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.
+ -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 4. Increase for more comprehensive coverage at a
- cost of speed.
- -internal-stats - Generate internal analyzer statistics.
+ -maxloop <loop count>
+
+ Specifiy the number of times a block can be visited before giving up.
+ Default is 4. Increase for more comprehensive coverage at a cost of speed.
+
+ -internal-stats
+
+ Generate internal analyzer statistics.
+
+ --use-analyzer [Xcode|path to clang]
+ --use-analyzer=[Xcode|path to clang]
+ scan-build uses the 'clang' executable relative to itself for static
+ analysis. One can override this behavior with this option by using the
+ 'clang' packaged with Xcode (on OS X) or from the PATH.
+
CONTROLLING CHECKERS:
A default group of checkers are always run unless explicitly disabled.
@@ -1119,85 +1135,86 @@ foreach my $lang ("c", "objective-c", "objective-c++", "c++") {
}
# Query clang for complete list of checkers.
-pipe(FROM_CHILD, TO_PARENT);
-my $pid = fork();
-if ($pid == 0) {
- close FROM_CHILD;
- open(STDOUT,">&", \*TO_PARENT);
- open(STDERR,">&", \*TO_PARENT);
- exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help');
-}
-close(TO_PARENT);
-my $foundCheckers = 0;
-while(<FROM_CHILD>) {
- if (/CHECKERS:/) {
- $foundCheckers = 1;
- last;
+if (defined $Clang && -x $Clang) {
+ pipe(FROM_CHILD, TO_PARENT);
+ my $pid = fork();
+ if ($pid == 0) {
+ close FROM_CHILD;
+ open(STDOUT,">&", \*TO_PARENT);
+ open(STDERR,">&", \*TO_PARENT);
+ exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help');
}
-}
-if (!$foundCheckers) {
- print " *** Could not query Clang for the list of available checkers.";
-}
-else {
- print("\nAVAILABLE CHECKERS:\n\n");
- my $skip = 0;
+ close(TO_PARENT);
+ my $foundCheckers = 0;
while(<FROM_CHILD>) {
- if (/experimental/) {
- $skip = 1;
- next;
- }
- if ($skip) {
- next if (!/^\s\s[^\s]/);
- $skip = 0;
+ if (/CHECKERS:/) {
+ $foundCheckers = 1;
+ last;
}
- s/^\s\s//;
- if (/^([^\s]+)/) {
- # Is the checker enabled?
- my $checker = $1;
- my $enabled = 0;
- my $aggregate = "";
- foreach my $domain (split /\./, $checker) {
- $aggregate .= $domain;
- if ($EnabledCheckers{$aggregate}) {
- $enabled =1;
- last;
- }
- # append a dot, if an additional domain is added in the next iteration
- $aggregate .= ".";
+ }
+ if (!$foundCheckers) {
+ print " *** Could not query Clang for the list of available checkers.";
+ }
+ else {
+ print("\nAVAILABLE CHECKERS:\n\n");
+ my $skip = 0;
+ while(<FROM_CHILD>) {
+ if (/experimental/) {
+ $skip = 1;
+ next;
+ }
+ if ($skip) {
+ next if (!/^\s\s[^\s]/);
+ $skip = 0;
}
+ s/^\s\s//;
+ if (/^([^\s]+)/) {
+ # Is the checker enabled?
+ my $checker = $1;
+ my $enabled = 0;
+ my $aggregate = "";
+ foreach my $domain (split /\./, $checker) {
+ $aggregate .= $domain;
+ if ($EnabledCheckers{$aggregate}) {
+ $enabled =1;
+ last;
+ }
+ # append a dot, if an additional domain is added in the next iteration
+ $aggregate .= ".";
+ }
- if ($enabled) {
- print " + ";
+ if ($enabled) {
+ print " + ";
+ }
+ else {
+ print " ";
+ }
}
else {
print " ";
}
+ print $_;
}
- else {
- print " ";
- }
- print $_;
- }
+ print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n"
+ }
+ waitpid($pid,0);
+ close(FROM_CHILD);
}
-waitpid($pid,0);
-close(FROM_CHILD);
print <<ENDTEXT
- NOTE: "+" indicates that an analysis is enabled by default.
-
BUILD OPTIONS
You can specify any build option acceptable to the build command.
EXAMPLE
- $Prog -o /tmp/myhtmldir make -j4
+ scan-build -o /tmp/myhtmldir make -j4
- The above example causes analysis reports to be deposited into
- a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option.
- A different subdirectory is created each time $Prog analyzes a project.
- The analyzer should support most parallel builds, but not distributed builds.
+The above example causes analysis reports to be deposited into a subdirectory
+of "/tmp/myhtmldir" and to run "make" with the "-j4" option. A different
+subdirectory is created each time scan-build analyzes a project. The analyzer
+should support most parallel builds, but not distributed builds.
ENDTEXT
}
@@ -1251,6 +1268,7 @@ if (!@ARGV) {
my $displayHelp = 0;
+my $AnalyzerDiscoveryMethod;
while (@ARGV) {
@@ -1418,6 +1436,16 @@ while (@ARGV) {
push @PluginsToLoad, "-load", shift @ARGV;
next;
}
+ if ($arg eq "--use-analyzer") {
+ shift @ARGV;
+ $AnalyzerDiscoveryMethod = shift @ARGV;
+ next;
+ }
+ if ($arg =~ /^--use-analyzer=(.+)$/) {
+ shift @ARGV;
+ $AnalyzerDiscoveryMethod = $1;
+ next;
+ }
DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
@@ -1429,11 +1457,50 @@ if (!@ARGV and $displayHelp == 0) {
$displayHelp = 1;
}
+# Find 'clang'
+if (!defined $AnalyzerDiscoveryMethod) {
+ $Clang = Cwd::realpath("$RealBin/bin/clang");
+ if (!defined $Clang || ! -x $Clang) {
+ $Clang = Cwd::realpath("$RealBin/clang");
+ }
+ if (!defined $Clang || ! -x $Clang) {
+ if (!$displayHelp) {
+ DieDiag("error: Cannot find an executable 'clang' relative to scan-build." .
+ " Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n");
+ }
+ }
+}
+else {
+ if ($AnalyzerDiscoveryMethod =~ /^[Xx]code$/) {
+ my $xcrun = `which xcrun`;
+ chomp $xcrun;
+ if ($xcrun eq "") {
+ DieDiag("Cannot find 'xcrun' to find 'clang' for analysis.\n");
+ }
+ $Clang = `$xcrun -toolchain XcodeDefault -find clang`;
+ chomp $Clang;
+ if ($Clang eq "") {
+ DieDiag("No 'clang' executable found by 'xcrun'\n");
+ }
+ }
+ else {
+ $Clang = Cwd::realpath($AnalyzerDiscoveryMethod);
+ if (! -x $Clang) {
+ DieDiag("Cannot find an executable clang at '$Clang'\n");
+ }
+ }
+}
+
if ($displayHelp) {
DisplayHelp();
exit 1;
}
+$ClangCXX = $Clang;
+$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX .= "++";
+$ClangVersion = HtmlEscape(`$Clang --version`);
+
# Determine where results go.
$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV)));
$HtmlTitle = "${CurrentDirSuffix} - scan-build results"
@@ -1457,15 +1524,12 @@ if (!defined $CmdCXX || ! -x $CmdCXX) {
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: $Clang\n");
-}
+Diag("Using '$Clang' for static analysis\n");
SetHtmlEnv(\@ARGV, $HtmlDir);
if ($AnalyzeHeaders) { push @AnalysesToRun,"-analyzer-opt-analyze-headers"; }
if ($AnalyzerStats) { push @AnalysesToRun, '-analyzer-checker=debug.Stats'; }
-if ($MaxLoop > 0) { push @AnalysesToRun, '-analyzer-max-loop=$MaxLoop'; }
+if ($MaxLoop > 0) { push @AnalysesToRun, "-analyzer-max-loop $MaxLoop"; }
# Delay setting up other environment variables in case we can do true
# interposition.
diff --git a/tools/scan-build/scan-build.1 b/tools/scan-build/scan-build.1
index 0f43196..0c7ef1d 100644
--- a/tools/scan-build/scan-build.1
+++ b/tools/scan-build/scan-build.1
@@ -1,9 +1,9 @@
.\" This file is distributed under the University of Illinois Open Source
.\" License. See LICENSE.TXT for details.
-.\" $Id: scan-build.1 157412 2012-05-24 20:16:00Z kremenek $
+.\" $Id: scan-build.1 167537 2012-11-07 17:12:37Z jrose $
.Dd May 25, 2012
+.Dt SCAN-BUILD 1
.Os "clang" "3.1"
-.Dt SCAN-BUILD \&1 CLANG
.Sh NAME
.Nm scan-build
.Nd Clang static analyzer
@@ -139,7 +139,7 @@ which is far less precise but can more quickly analyze code.
was the default store model for checker-0.221 and earlier.
.\"
.El
-.Sh RETURN VALUES
+.Sh EXIT STATUS
.Nm
returns the value returned by
.Ar build_command
@@ -188,10 +188,10 @@ Check for undefined results of binary operators.
.It core.VLASize
Check for declarations of VLA of undefined or zero size.
.It core.builtin.BuiltinFunctions
-Evaluate compiler builtin functions, e.g.
+Evaluate compiler builtin functions, e.g.
.Fn alloca .
.It core.builtin.NoReturnFunctions
-Evaluate
+Evaluate
.Ql panic
functions that are known to not return to the caller.
.It core.uninitialized.ArraySubscript
@@ -270,9 +270,10 @@ Check for proper uses of
.Fn CFNumberCreate .
.It osx.coreFoundation.CFRetainRelease
Check for null arguments to
-.Fn CFRetain
+.Fn CFRetain ,
+.Fn CFRelease ,
and
-.Fn CFRelease .
+.Fn CFMakeCollectable .
.It osx.coreFoundation.containers.OutOfBounds
Checks for index out-of-bounds when using the
.Vt CFArray
diff --git a/tools/scan-build/set-xcode-analyzer b/tools/scan-build/set-xcode-analyzer
index c280bb4..93824af 100755
--- a/tools/scan-build/set-xcode-analyzer
+++ b/tools/scan-build/set-xcode-analyzer
@@ -20,10 +20,19 @@ def FindClangSpecs(path):
if f.endswith(".xcspec") and f.startswith("Clang LLVM"):
yield os.path.join(root, f)
-def ModifySpec(path, pathToChecker):
+def ModifySpec(path, isBuiltinAnalyzer, pathToChecker):
t = tempfile.NamedTemporaryFile(delete=False)
foundAnalyzer = False
with open(path) as f:
+ if isBuiltinAnalyzer:
+ # First search for CLANG_ANALYZER_EXEC. Newer
+ # versions of Xcode set EXEC_PATH to be CLANG_ANALYZER_EXEC.
+ with open(path) as f2:
+ for line in f2:
+ if line.find("CLANG_ANALYZER_EXEC") >= 0:
+ pathToChecker = "$(CLANG_ANALYZER_EXEC)"
+ break
+ # Now create a new file.
for line in f:
if not foundAnalyzer:
if line.find("Static Analyzer") >= 0:
@@ -63,6 +72,7 @@ def main():
print "(-) You must quit Xcode first before modifying its configuration files."
return
+ isBuiltinAnalyzer = False
if options.path:
# Expand tildes.
path = os.path.expanduser(options.path)
@@ -74,19 +84,25 @@ def main():
else:
print "(+) Using the Clang bundled with Xcode"
path = options.default
+ isBuiltinAnalyzer = True
try:
xcode_path = subprocess.check_output(["xcode-select", "-print-path"])
except AttributeError:
# Fall back to the default install location when using Python < 2.7.0
xcode_path = "/Developer"
- if (re.search("Xcode.app", xcode_path)):
+ if (xcode_path.find(".app/") != -1):
# Cut off the 'Developer' dir, as the xcspec lies in another part
# of the Xcode.app subtree.
xcode_path = os.path.dirname(xcode_path)
+ foundSpec = False
for x in FindClangSpecs(xcode_path):
- ModifySpec(x, path)
+ foundSpec = True
+ ModifySpec(x, isBuiltinAnalyzer, path)
+
+ if foundSpec == False:
+ print "(-) No compiler configuration file was found. Xcode's analyzer has not been updated."
if __name__ == '__main__':
main()
OpenPOWER on IntegriCloud