blob: 5f61132c73dcddccf1963be26b3f9cf5d67b6d99 [file] [log] [blame]
# Temporarily disable tautological-*-compare chromium:778316.
# Temporarily add no-unknown-warning-option to deal with old clang versions.
FLAGS_TO_ADD = set((
'-Wno-unused-local-typedefs',
'-Wno-deprecated-declarations',
'-Wno-tautological-constant-compare',
'-Wno-tautological-unsigned-enum-zero-compare',
'-Wno-unknown-warning-option',
))
def exec_and_bisect(execargs, bisect_stage, argv0):
"""Execute compiler, return and invoke bisection driver."""
import bisect_driver
bisect_dir = os.environ.get('BISECT_DIR', '/tmp/sysroot_bisect')
try:
ret = bisect_driver.bisect_driver(bisect_stage, bisect_dir, execargs)
except OSError as e:
handle_exec_exception(e, argv0, execargs)
sys.exit(ret)
def main(argv):
"""Main function for clang wrapper script."""
# Only FORTIFY_SOURCE hardening flag is applicable for clang.
clang_flags = [
'-Qunused-arguments',
'-grecord-gcc-switches',
'-fno-addrsig',
'-fuse-ld=lld',
]
use_clang_tidy = os.environ.get('WITH_TIDY')
if use_clang_tidy:
c_src_file = find_source_file(argv)
if not c_src_file:
use_clang_tidy = False
else:
c_src_file = ''
myargs = argv[1:]
bisect_stage = os.environ.get('BISECT_STAGE')
print_cmdline = '-print-cmdline' in myargs
# Filter unsupported linker flags if sanitizers are used.
filter_unsupported_asan_flags = has_sanitizer_flags(myargs)
clang_cmdline = clang_flags + list(LLVM_NEXT_FLAGS_TO_ADD) + list(FLAGS_TO_ADD)
clang_flags = list(FLAGS_TO_ADD)
cmdline = [x for x in myargs if x not in WRAPPER_ONLY_OPTIONS]
if filter_unsupported_asan_flags:
cmdline = [x for x in cmdline if x not in UNSUPPORTED_ASAN_FLAGS]
clang_cmdline = [x for x in clang_cmdline if x not in UNSUPPORTED_ASAN_FLAGS]
# Add flags for fuzzer.
if has_fuzzer_flags(myargs):
clang_cmdline.extend(FUZZER_FLAGS_TO_ADD)
prog_base = os.path.basename(sys.argv[0])
if prog_base.startswith('x86_64') or startswith_i86(prog_base):
cmdline.extend(X86_DISABLE_FLAGS)
sysroot = os.environ.get('SYSROOT', '/')
# Get the clang binary location relative to the wrapper.
clang_bin = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'clang')
for flag in cmdline:
if not (flag in CLANG_UNSUPPORTED or
flag.startswith(CLANG_UNSUPPORTED_PREFIXES)):
# Strip off -Xclang-only= if present.
if flag.startswith('-Xclang-only='):
opt = flag.partition('=')[2]
clang_cmdline.append(opt)
elif flag.startswith('-Xclang-path='):
import subprocess
# Use clang installed at the given path. But use the resource directory
# for the main clang since the custom clang installation won't have
# the cross-target libraries.
resource_path = subprocess.check_output([clang_bin,
'--print-resource-dir'])
clang_cmdline.append('-resource-dir=%s' % resource_path.strip())
clang_cmdline.append('--gcc-toolchain=/usr')
clang_path = flag.partition('=')[2]
clang_bin = os.path.join(clang_path, 'clang')
elif flag in GCC_TO_CLANG.keys():
clang_cmdline.append(GCC_TO_CLANG[flag])
elif not flag in CLANG_ARM_OPTIONS_TO_BE_DISCARDED:
clang_cmdline.append(flag)
clang_tidy_bin = clang_bin + '-tidy'
clang_comp = os.environ.get('CLANG', clang_bin)
# Check for clang or clang++.
if sys.argv[0].endswith('++'):
clang_comp += '++'
execargs = []
argv0 = clang_comp
execargs += [clang_comp] + clang_cmdline
if use_clang_tidy:
import subprocess
tidy_execargs = []
default_tidy_checks = ','.join([
'*',
'google*',
'-bugprone-narrowing-conversions',
'-cppcoreguidelines-*',
'-fuchsia-*',
'-google-build-using-namespace',
'-google-default-arguments',
'-google-explicit-constructor',
'-google-readability*',
'-google-runtime-int',
'-google-runtime-references',
'-hicpp-avoid-c-arrays',
'-hicpp-braces-around-statements',
'-hicpp-no-array-decay',
'-hicpp-signed-bitwise',
'-hicpp-uppercase-literal-suffix',
'-hicpp-use-auto',
'-llvm-namespace-comment',
'-misc-non-private-member-variables-in-classes',
'-misc-unused-parameters',
'-modernize-*',
'-readability-*',
])
tidy_args = ['-checks=' + default_tidy_checks]
resource_path = subprocess.check_output([clang_comp,
'--print-resource-dir'])
resource_dir_arg = ['-resource-dir=%s' % resource_path.strip()]
tidy_execargs += [clang_tidy_bin] + tidy_args + [c_src_file] + ['--'] \
+ resource_dir_arg + clang_cmdline
if print_cmdline:
print("Calling clang-tidy:")
print(repr(tidy_execargs))
retval = subprocess.call(tidy_execargs)
if retval != 0 and print_cmdline:
print("Call to clang-tidy failed!")
if print_cmdline:
print('[%s] %s' % (argv0, ' '.join(execargs)))
sys.stdout.flush()
# We'll sometimes pull in a new compiler (or similar) and want a good way of
# vetting it. New warnings are useful, but actively block the potentially more
# interesting things (actually building the world, testing, etc). This is our
# escape hatch.
if os.getenv('FORCE_DISABLE_WERROR'):
sys.exit(double_build_with_wno_error(execargs))
if not bisect_stage:
try:
os.execv(argv0, execargs)
except OSError as e:
handle_exec_exception(e, argv0, False, execargs)
# Only comes here if doing bisection.
exec_and_bisect(execargs, bisect_stage, argv0)
if __name__ == '__main__':
sys.exit(main(sys.argv))