diff options
author | Yury Gribov <y.gribov@samsung.com> | 2016-02-18 11:08:46 +0000 |
---|---|---|
committer | Yury Gribov <y.gribov@samsung.com> | 2016-02-18 11:08:46 +0000 |
commit | 19b977bcdf62a9f6fca2c115fd85d2508f4a818b (patch) | |
tree | 374e6633bb249255b0145f0981f103370ca63064 /tools/scan-build-py | |
parent | dcd61b3089babf56947b8be5487e410ac195b380 (diff) | |
download | clang-19b977bcdf62a9f6fca2c115fd85d2508f4a818b.tar.gz |
[analyzer] Add --force-analyze-debug-code option to scan-build
to force debug build and hopefully enable more precise warnings.
Static Analyzer is much more efficient when built in debug mode
(-UNDEBUG) so we advice users to enable it manually. This may be
inconvenient in case of large complex projects (think about Linux
distros e.g. Android or Tizen). This patch adds a flag to scan-build
which inserts -UNDEBUG automatically.
Differential Revision: http://reviews.llvm.org/D16200
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261204 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/scan-build-py')
-rw-r--r-- | tools/scan-build-py/libscanbuild/analyze.py | 16 | ||||
-rw-r--r-- | tools/scan-build-py/libscanbuild/runner.py | 11 | ||||
-rw-r--r-- | tools/scan-build-py/tests/unit/test_runner.py | 11 |
3 files changed, 34 insertions, 4 deletions
diff --git a/tools/scan-build-py/libscanbuild/analyze.py b/tools/scan-build-py/libscanbuild/analyze.py index 0d3547befe..9b00d04fc0 100644 --- a/tools/scan-build-py/libscanbuild/analyze.py +++ b/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/tools/scan-build-py/libscanbuild/runner.py b/tools/scan-build-py/libscanbuild/runner.py index 248ca90ad3..63b9f74369 100644 --- a/tools/scan-build-py/libscanbuild/runner.py +++ b/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/tools/scan-build-py/tests/unit/test_runner.py b/tools/scan-build-py/tests/unit/test_runner.py index ea10051d85..de15d23692 100644 --- a/tools/scan-build-py/tests/unit/test_runner.py +++ b/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) |