summaryrefslogtreecommitdiff
path: root/tools/scan-build-py
diff options
context:
space:
mode:
authorYury Gribov <y.gribov@samsung.com>2016-02-18 11:08:46 +0000
committerYury Gribov <y.gribov@samsung.com>2016-02-18 11:08:46 +0000
commit19b977bcdf62a9f6fca2c115fd85d2508f4a818b (patch)
tree374e6633bb249255b0145f0981f103370ca63064 /tools/scan-build-py
parentdcd61b3089babf56947b8be5487e410ac195b380 (diff)
downloadclang-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.py16
-rw-r--r--tools/scan-build-py/libscanbuild/runner.py11
-rw-r--r--tools/scan-build-py/tests/unit/test_runner.py11
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)