summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/tools/scan-build-py/libscanbuild/analyze.py16
-rw-r--r--clang/tools/scan-build-py/libscanbuild/runner.py11
-rw-r--r--clang/tools/scan-build-py/tests/unit/test_runner.py11
-rwxr-xr-xclang/tools/scan-build/bin/scan-build20
-rwxr-xr-xclang/tools/scan-build/libexec/ccc-analyzer8
-rw-r--r--clang/www/analyzer/scan-build.html3
6 files changed, 62 insertions, 7 deletions
diff --git a/clang/tools/scan-build-py/libscanbuild/analyze.py b/clang/tools/scan-build-py/libscanbuild/analyze.py
index 0d3547befee..9b00d04fc0f 100644
--- a/clang/tools/scan-build-py/libscanbuild/analyze.py
+++ b/clang/tools/scan-build-py/libscanbuild/analyze.py
@@ -106,7 +106,8 @@ def run_analyzer(args, output_dir):
'output_dir': output_dir,
'output_format': args.output_format,
'output_failures': args.output_failures,
- 'direct_args': analyzer_params(args)
+ 'direct_args': analyzer_params(args),
+ 'force_analyze_debug_code' : args.force_analyze_debug_code
}
logging.debug('run analyzer against compilation database')
@@ -138,7 +139,9 @@ def setup_environment(args, destination, bin_dir):
'ANALYZE_BUILD_REPORT_DIR': destination,
'ANALYZE_BUILD_REPORT_FORMAT': args.output_format,
'ANALYZE_BUILD_REPORT_FAILURES': 'yes' if args.output_failures else '',
- 'ANALYZE_BUILD_PARAMETERS': ' '.join(analyzer_params(args))
+ 'ANALYZE_BUILD_PARAMETERS': ' '.join(analyzer_params(args)),
+ 'ANALYZE_BUILD_FORCE_ANALYZE_DEBUG_CODE'
+ : 'yes' if args.force_analyze_debug_code else ''
})
return environment
@@ -168,6 +171,8 @@ def analyze_build_wrapper(cplusplus):
'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
'').split(' '),
+ 'force_analyze_debug_code':
+ os.getenv('ANALYZE_BUILD_FORCE_ANALYZE_DEBUG_CODE'),
'directory': os.getcwd(),
}
# get relevant parameters from command line arguments
@@ -450,6 +455,13 @@ def create_parser(from_build_command):
Could be usefull when project contains 3rd party libraries.
The directory path shall be absolute path as file names in
the compilation database.""")
+ advanced.add_argument(
+ '--force-analyze-debug-code',
+ dest='force_analyze_debug_code',
+ action='store_true',
+ help="""Tells analyzer to enable assertions in code even if they were
+ disabled during compilation, enabling more precise
+ results.""")
plugins = parser.add_argument_group('checker options')
plugins.add_argument(
diff --git a/clang/tools/scan-build-py/libscanbuild/runner.py b/clang/tools/scan-build-py/libscanbuild/runner.py
index 248ca90ad3e..63b9f743699 100644
--- a/clang/tools/scan-build-py/libscanbuild/runner.py
+++ b/clang/tools/scan-build-py/libscanbuild/runner.py
@@ -41,6 +41,7 @@ def require(required):
@require(['command', 'directory', 'file', # an entry from compilation database
'clang', 'direct_args', # compiler name, and arguments from command
+ 'force_analyze_debug_code', # preprocessing options
'output_dir', 'output_format', 'output_failures'])
def run(opts):
""" Entry point to run (or not) static analyzer against a single entry
@@ -164,9 +165,13 @@ def set_analyzer_output(opts, continuation=run_analyzer):
opts.update({'output': ['-o', opts['output_dir']]})
return continuation(opts)
+def force_analyze_debug_code(cmd):
+ """ Enable assert()'s by undefining NDEBUG. """
+ cmd.append('-UNDEBUG')
-@require(['file', 'directory', 'clang', 'direct_args', 'language',
- 'output_dir', 'output_format', 'output_failures'])
+@require(['file', 'directory', 'clang', 'direct_args',
+ 'force_analyze_debug_code', 'language', 'output_dir',
+ 'output_format', 'output_failures'])
def create_commands(opts, continuation=set_analyzer_output):
""" Create command to run analyzer or failure report generation.
@@ -178,6 +183,8 @@ def create_commands(opts, continuation=set_analyzer_output):
if 'arch' in opts:
common.extend(['-arch', opts.pop('arch')])
common.extend(opts.pop('compile_options', []))
+ if opts['force_analyze_debug_code']:
+ force_analyze_debug_code(common)
common.extend(['-x', opts['language']])
common.append(os.path.relpath(opts['file'], opts['directory']))
diff --git a/clang/tools/scan-build-py/tests/unit/test_runner.py b/clang/tools/scan-build-py/tests/unit/test_runner.py
index ea10051d850..de15d236920 100644
--- a/clang/tools/scan-build-py/tests/unit/test_runner.py
+++ b/clang/tools/scan-build-py/tests/unit/test_runner.py
@@ -211,3 +211,14 @@ class RequireDecoratorTest(unittest.TestCase):
def test_method_exception_not_caught(self):
self.assertRaises(Exception, method_exception_from_inside, dict())
+
+class ForceAnalyzeDebugTest(unittest.TestCase):
+
+ def test_force_analyze_debug_code(self):
+ for a, b in [
+ ([], ['-UNDEBUG']),
+ (['-O2'], ['-O2', '-UNDEBUG']),
+ (['-Dkey=val'], ['-Dkey=val', '-UNDEBUG']),
+ (['-D', 'NDEBUG'], ['-D', 'NDEBUG', '-UNDEBUG']) ]:
+ sut.force_analyze_debug_code(a)
+ self.assertEqual(a, b)
diff --git a/clang/tools/scan-build/bin/scan-build b/clang/tools/scan-build/bin/scan-build
index 6a14484970a..3182a29767b 100755
--- a/clang/tools/scan-build/bin/scan-build
+++ b/clang/tools/scan-build/bin/scan-build
@@ -69,7 +69,8 @@ my %Options = (
MaxLoop => 0,
PluginsToLoad => [],
AnalyzerDiscoveryMethod => undef,
- OverrideCompiler => 0 # The flag corresponding to the --override-compiler command line option.
+ OverrideCompiler => 0, # The flag corresponding to the --override-compiler command line option.
+ ForceAnalyzeDebugCode => 0
);
lock_keys(%Options);
@@ -951,7 +952,8 @@ sub SetEnv {
'CCC_CC',
'CCC_CXX',
'CCC_REPORT_FAILURES',
- 'CLANG_ANALYZER_TARGET') {
+ 'CLANG_ANALYZER_TARGET',
+ 'CCC_ANALYZER_FORCE_ANALYZE_DEBUG_CODE') {
my $x = $EnvVars->{$var};
if (defined $x) { $ENV{$var} = $x }
}
@@ -1118,6 +1120,11 @@ OPTIONS:
Also analyze functions in #included files. By default, such functions
are skipped unless they are called by functions within the main source file.
+ --force-analyze-debug-code
+
+ Tells analyzer to enable assertions in code even if they were disabled
+ during compilation to enable more precise results.
+
-o <output location>
Specifies the output directory for analyzer reports. Subdirectories will be
@@ -1681,6 +1688,12 @@ sub ProcessArgs {
next;
}
+ if ($arg eq "--force-analyze-debug-code") {
+ shift @$Args;
+ $Options{ForceAnalyzeDebugCode} = 1;
+ next;
+ }
+
DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
$NumArgs--;
@@ -1796,7 +1809,8 @@ my %EnvVars = (
'CCC_ANALYZER_CONSTRAINTS_MODEL' => $Options{ConstraintsModel},
'CCC_ANALYZER_INTERNAL_STATS' => $Options{InternalStats},
'CCC_ANALYZER_OUTPUT_FORMAT' => $Options{OutputFormat},
- 'CLANG_ANALYZER_TARGET' => $Options{AnalyzerTarget}
+ 'CLANG_ANALYZER_TARGET' => $Options{AnalyzerTarget},
+ 'CCC_ANALYZER_FORCE_ANALYZE_DEBUG_CODE' => $Options{ForceAnalyzeDebugCode}
);
# Run the build.
diff --git a/clang/tools/scan-build/libexec/ccc-analyzer b/clang/tools/scan-build/libexec/ccc-analyzer
index 831dd42e9c9..bfda1d326f9 100755
--- a/clang/tools/scan-build/libexec/ccc-analyzer
+++ b/clang/tools/scan-build/libexec/ccc-analyzer
@@ -492,6 +492,9 @@ if (defined $ENV{'CCC_ANALYZER_LOG'}) { $Verbose = 2; }
# Get the HTML output directory.
my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
+# Get force-analyze-debug-code option.
+my $ForceAnalyzeDebugCode = $ENV{'CCC_ANALYZER_FORCE_ANALYZE_DEBUG_CODE'};
+
my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1);
my %ArchsSeen;
my $HadArch = 0;
@@ -682,6 +685,11 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
}
}
+# Forcedly enable debugging if requested by user.
+if ($ForceAnalyzeDebugCode) {
+ push @CompileOpts, '-UNDEBUG';
+}
+
# If we are on OSX and have an installation where the
# default SDK is inferred by xcrun use xcrun to infer
# the SDK.
diff --git a/clang/www/analyzer/scan-build.html b/clang/www/analyzer/scan-build.html
index 04e93232a6b..b16f6bb53fa 100644
--- a/clang/www/analyzer/scan-build.html
+++ b/clang/www/analyzer/scan-build.html
@@ -226,6 +226,9 @@ Assertions are picked up by the static analyzer to prune infeasible paths, which
in some cases can greatly reduce the number of false positives (bogus error
reports) emitted by the tool.</p>
+<p>Another option is to use <tt>--force-analyze-debug-code</tt> flag of
+<b>scan-build</b> tool which would enable assertions automatically.</p>
+
<h3 id="recommend_verbose">Use verbose output when debugging scan-build</h3>
<p><tt>scan-build</tt> takes a <b>-v</b> option to emit verbose output about
OpenPOWER on IntegriCloud