diff --git a/clang/tools/scan-build-py/libscanbuild/analyze.py b/clang/tools/scan-build-py/libscanbuild/analyze.py --- a/clang/tools/scan-build-py/libscanbuild/analyze.py +++ b/clang/tools/scan-build-py/libscanbuild/analyze.py @@ -33,7 +33,8 @@ from libscanbuild.report import document from libscanbuild.compilation import split_command, classify_source, \ compiler_language -from libscanbuild.clang import get_version, get_arguments, get_triple_arch +from libscanbuild.clang import get_version, get_arguments, get_triple_arch, \ + ClangErrorException from libscanbuild.shell import decode __all__ = ['scan_build', 'analyze_build', 'analyze_compiler_wrapper'] @@ -435,7 +436,7 @@ of the compilation database. This complex task is decomposed into smaller methods which are calling - each other in chain. If the analyzis is not possible the given method + each other in chain. If the analysis is not possible the given method just return and break the chain. The passed parameter is a python dictionary. Each method first check @@ -451,7 +452,7 @@ return arch_check(opts) except Exception: - logging.error("Problem occurred during analyzis.", exc_info=1) + logging.error("Problem occurred during analysis.", exc_info=1) return None @@ -490,10 +491,15 @@ os.close(handle) # Execute Clang again, but run the syntax check only. cwd = opts['directory'] - cmd = get_arguments( - [opts['clang'], '-fsyntax-only', '-E' - ] + opts['flags'] + [opts['file'], '-o', name], cwd) - run_command(cmd, cwd=cwd) + cmd = [opts['clang'], '-fsyntax-only', '-E'] + opts['flags'] + \ + [opts['file'], '-o', name] + try: + cmd = get_arguments(cmd, cwd) + run_command(cmd, cwd=cwd) + except subprocess.CalledProcessError: + pass + except ClangErrorException: + pass # write general information about the crash with open(name + '.info.txt', 'w') as handle: handle.write(opts['file'] + os.linesep) @@ -542,6 +548,12 @@ opts.update(result) continuation(opts) return result + except ClangErrorException as ex: + result = {'error_output': ex.error, 'exit_code': 0} + if opts.get('output_failures', False): + opts.update(result) + continuation(opts) + return result def extdef_map_list_src_to_ast(extdef_src_list): diff --git a/clang/tools/scan-build-py/libscanbuild/clang.py b/clang/tools/scan-build-py/libscanbuild/clang.py --- a/clang/tools/scan-build-py/libscanbuild/clang.py +++ b/clang/tools/scan-build-py/libscanbuild/clang.py @@ -19,6 +19,11 @@ ACTIVE_CHECKER_PATTERN = re.compile(r'^-analyzer-checker=(.*)$') +class ClangErrorException(Exception): + def __init__(self, error): + self.error = error + + def get_version(clang): """ Returns the compiler version as string. @@ -39,13 +44,14 @@ cmd = command[:] cmd.insert(1, '-###') + cmd.append('-fno-color-diagnostics') output = run_command(cmd, cwd=cwd) # The relevant information is in the last line of the output. # Don't check if finding last line fails, would throw exception anyway. last_line = output[-1] if re.search(r'clang(.*): error:', last_line): - raise Exception(last_line) + raise ClangErrorException(last_line) return decode(last_line)