'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')
'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
'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
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(
@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
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.
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']))
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)
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);
'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 }
}
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
next;
}
+ if ($arg eq "--force-analyze-debug-code") {
+ shift @$Args;
+ $Options{ForceAnalyzeDebugCode} = 1;
+ next;
+ }
+
DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
$NumArgs--;
'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.
# 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;
}
}
+# 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.
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