Home | History | Annotate | Download | only in test
      1 #===----------------------------------------------------------------------===##
      2 #
      3 #                     The LLVM Compiler Infrastructure
      4 #
      5 # This file is dual licensed under the MIT and the University of Illinois Open
      6 # Source Licenses. See LICENSE.TXT for details.
      7 #
      8 #===----------------------------------------------------------------------===##
      9 
     10 import locale
     11 import os
     12 import platform
     13 import pkgutil
     14 import re
     15 import shlex
     16 import sys
     17 
     18 import lit.Test  # pylint: disable=import-error,no-name-in-module
     19 import lit.util  # pylint: disable=import-error,no-name-in-module
     20 
     21 from libcxx.test.format import LibcxxTestFormat
     22 from libcxx.compiler import CXXCompiler
     23 from libcxx.test.target_info import make_target_info
     24 from libcxx.test.executor import *
     25 from libcxx.test.tracing import *
     26 
     27 def loadSiteConfig(lit_config, config, param_name, env_name):
     28     # We haven't loaded the site specific configuration (the user is
     29     # probably trying to run on a test file directly, and either the site
     30     # configuration hasn't been created by the build system, or we are in an
     31     # out-of-tree build situation).
     32     site_cfg = lit_config.params.get(param_name,
     33                                      os.environ.get(env_name))
     34     if not site_cfg:
     35         lit_config.warning('No site specific configuration file found!'
     36                            ' Running the tests in the default configuration.')
     37     elif not os.path.isfile(site_cfg):
     38         lit_config.fatal(
     39             "Specified site configuration file does not exist: '%s'" %
     40             site_cfg)
     41     else:
     42         lit_config.note('using site specific configuration at %s' % site_cfg)
     43         ld_fn = lit_config.load_config
     44 
     45         # Null out the load_config function so that lit.site.cfg doesn't
     46         # recursively load a config even if it tries.
     47         # TODO: This is one hell of a hack. Fix it.
     48         def prevent_reload_fn(*args, **kwargs):
     49             pass
     50         lit_config.load_config = prevent_reload_fn
     51         ld_fn(config, site_cfg)
     52         lit_config.load_config = ld_fn
     53 
     54 class Configuration(object):
     55     # pylint: disable=redefined-outer-name
     56     def __init__(self, lit_config, config):
     57         self.lit_config = lit_config
     58         self.config = config
     59         self.cxx = None
     60         self.project_obj_root = None
     61         self.libcxx_src_root = None
     62         self.libcxx_obj_root = None
     63         self.cxx_library_root = None
     64         self.cxx_runtime_root = None
     65         self.abi_library_root = None
     66         self.env = {}
     67         self.use_target = False
     68         self.use_system_cxx_lib = False
     69         self.use_clang_verify = False
     70         self.long_tests = None
     71         self.execute_external = False
     72 
     73     def get_lit_conf(self, name, default=None):
     74         val = self.lit_config.params.get(name, None)
     75         if val is None:
     76             val = getattr(self.config, name, None)
     77             if val is None:
     78                 val = default
     79         return val
     80 
     81     def get_lit_bool(self, name, default=None):
     82         conf = self.get_lit_conf(name)
     83         if conf is None:
     84             return default
     85         if conf.lower() in ('1', 'true'):
     86             return True
     87         if conf.lower() in ('', '0', 'false'):
     88             return False
     89         self.lit_config.fatal(
     90             "parameter '{}' should be true or false".format(name))
     91 
     92     def configure(self):
     93         self.configure_executor()
     94         self.configure_target_info()
     95         self.configure_cxx()
     96         self.configure_triple()
     97         self.configure_src_root()
     98         self.configure_obj_root()
     99         self.configure_cxx_library_root()
    100         self.configure_use_system_cxx_lib()
    101         self.configure_use_clang_verify()
    102         self.configure_use_thread_safety()
    103         self.configure_execute_external()
    104         self.configure_ccache()
    105         self.configure_compile_flags()
    106         self.configure_link_flags()
    107         self.configure_env()
    108         self.configure_color_diagnostics()
    109         self.configure_debug_mode()
    110         self.configure_warnings()
    111         self.configure_sanitizer()
    112         self.configure_coverage()
    113         self.configure_substitutions()
    114         self.configure_features()
    115 
    116     def print_config_info(self):
    117         # Print the final compile and link flags.
    118         self.lit_config.note('Using compiler: %s' % self.cxx.path)
    119         self.lit_config.note('Using flags: %s' % self.cxx.flags)
    120         self.lit_config.note('Using compile flags: %s'
    121                              % self.cxx.compile_flags)
    122         self.lit_config.note('Using link flags: %s' % self.cxx.link_flags)
    123         # Print as list to prevent "set([...])" from being printed.
    124         self.lit_config.note('Using available_features: %s' %
    125                              list(self.config.available_features))
    126         self.lit_config.note('Using environment: %r' % self.env)
    127 
    128     def get_test_format(self):
    129         return LibcxxTestFormat(
    130             self.cxx,
    131             self.use_clang_verify,
    132             self.execute_external,
    133             self.executor,
    134             exec_env=self.env)
    135 
    136     def configure_executor(self):
    137         exec_str = self.get_lit_conf('executor', "None")
    138         te = eval(exec_str)
    139         if te:
    140             self.lit_config.note("Using executor: %r" % exec_str)
    141             if self.lit_config.useValgrind:
    142                 # We have no way of knowing where in the chain the
    143                 # ValgrindExecutor is supposed to go. It is likely
    144                 # that the user wants it at the end, but we have no
    145                 # way of getting at that easily.
    146                 selt.lit_config.fatal("Cannot infer how to create a Valgrind "
    147                                       " executor.")
    148         else:
    149             te = LocalExecutor()
    150             if self.lit_config.useValgrind:
    151                 te = ValgrindExecutor(self.lit_config.valgrindArgs, te)
    152         self.executor = te
    153 
    154     def configure_target_info(self):
    155         self.target_info = make_target_info(self)
    156 
    157     def configure_cxx(self):
    158         # Gather various compiler parameters.
    159         cxx = self.get_lit_conf('cxx_under_test')
    160 
    161         # If no specific cxx_under_test was given, attempt to infer it as
    162         # clang++.
    163         if cxx is None:
    164             clangxx = lit.util.which('clang++',
    165                                      self.config.environment['PATH'])
    166             if clangxx:
    167                 cxx = clangxx
    168                 self.lit_config.note(
    169                     "inferred cxx_under_test as: %r" % cxx)
    170         if not cxx:
    171             self.lit_config.fatal('must specify user parameter cxx_under_test '
    172                                   '(e.g., --param=cxx_under_test=clang++)')
    173         self.cxx = CXXCompiler(cxx)
    174         cxx_type = self.cxx.type
    175         if cxx_type is not None:
    176             assert self.cxx.version is not None
    177             maj_v, min_v, _ = self.cxx.version
    178             self.config.available_features.add(cxx_type)
    179             self.config.available_features.add('%s-%s.%s' % (
    180                 cxx_type, maj_v, min_v))
    181 
    182     def configure_src_root(self):
    183         self.libcxx_src_root = self.get_lit_conf(
    184             'libcxx_src_root', os.path.dirname(self.config.test_source_root))
    185 
    186     def configure_obj_root(self):
    187         self.project_obj_root = self.get_lit_conf('project_obj_root')
    188         self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
    189         if not self.libcxx_obj_root and self.project_obj_root is not None:
    190             possible_root = os.path.join(self.project_obj_root, 'projects', 'libcxx')
    191             if os.path.isdir(possible_root):
    192                 self.libcxx_obj_root = possible_root
    193             else:
    194                 self.libcxx_obj_root = self.project_obj_root
    195 
    196     def configure_cxx_library_root(self):
    197         self.cxx_library_root = self.get_lit_conf('cxx_library_root',
    198                                                   self.libcxx_obj_root)
    199         self.cxx_runtime_root = self.get_lit_conf('cxx_runtime_root',
    200                                                    self.cxx_library_root)
    201 
    202     def configure_use_system_cxx_lib(self):
    203         # This test suite supports testing against either the system library or
    204         # the locally built one; the former mode is useful for testing ABI
    205         # compatibility between the current headers and a shipping dynamic
    206         # library.
    207         self.use_system_cxx_lib = self.get_lit_bool('use_system_cxx_lib')
    208         if self.use_system_cxx_lib is None:
    209             # Default to testing against the locally built libc++ library.
    210             self.use_system_cxx_lib = False
    211             self.lit_config.note(
    212                 "inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
    213 
    214     def configure_use_clang_verify(self):
    215         '''If set, run clang with -verify on failing tests.'''
    216         self.use_clang_verify = self.get_lit_bool('use_clang_verify')
    217         if self.use_clang_verify is None:
    218             # NOTE: We do not test for the -verify flag directly because
    219             #   -verify will always exit with non-zero on an empty file.
    220             self.use_clang_verify = self.cxx.hasCompileFlag(
    221                 ['-Xclang', '-verify-ignore-unexpected'])
    222             self.lit_config.note(
    223                 "inferred use_clang_verify as: %r" % self.use_clang_verify)
    224 
    225     def configure_use_thread_safety(self):
    226         '''If set, run clang with -verify on failing tests.'''
    227         has_thread_safety = self.cxx.hasCompileFlag('-Werror=thread-safety')
    228         if has_thread_safety:
    229             self.cxx.compile_flags += ['-Werror=thread-safety']
    230             self.config.available_features.add('thread-safety')
    231             self.lit_config.note("enabling thread-safety annotations")
    232 
    233     def configure_execute_external(self):
    234         # Choose between lit's internal shell pipeline runner and a real shell.
    235         # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
    236         # default value. Otherwise we ask the target_info.
    237         use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
    238         if use_lit_shell_default is not None:
    239             use_lit_shell_default = use_lit_shell_default != '0'
    240         else:
    241             use_lit_shell_default = self.target_info.use_lit_shell_default()
    242         # Check for the command line parameter using the default value if it is
    243         # not present.
    244         use_lit_shell = self.get_lit_bool('use_lit_shell',
    245                                           use_lit_shell_default)
    246         self.execute_external = not use_lit_shell
    247 
    248     def configure_ccache(self):
    249         use_ccache_default = os.environ.get('LIBCXX_USE_CCACHE') is not None
    250         use_ccache = self.get_lit_bool('use_ccache', use_ccache_default)
    251         if use_ccache:
    252             self.cxx.use_ccache = True
    253             self.lit_config.note('enabling ccache')
    254 
    255     def configure_features(self):
    256         additional_features = self.get_lit_conf('additional_features')
    257         if additional_features:
    258             for f in additional_features.split(','):
    259                 self.config.available_features.add(f.strip())
    260         self.target_info.add_locale_features(self.config.available_features)
    261 
    262         target_platform = self.target_info.platform()
    263 
    264         # Write an "available feature" that combines the triple when
    265         # use_system_cxx_lib is enabled. This is so that we can easily write
    266         # XFAIL markers for tests that are known to fail with versions of
    267         # libc++ as were shipped with a particular triple.
    268         if self.use_system_cxx_lib:
    269             self.config.available_features.add(
    270                 'with_system_cxx_lib=%s' % self.config.target_triple)
    271 
    272         # Insert the platform name into the available features as a lower case.
    273         self.config.available_features.add(target_platform)
    274 
    275         # Simulator testing can take a really long time for some of these tests
    276         # so add a feature check so we can REQUIRES: long_tests in them
    277         self.long_tests = self.get_lit_bool('long_tests')
    278         if self.long_tests is None:
    279             # Default to running long tests.
    280             self.long_tests = True
    281             self.lit_config.note(
    282                 "inferred long_tests as: %r" % self.long_tests)
    283 
    284         if self.long_tests:
    285             self.config.available_features.add('long_tests')
    286 
    287         # Run a compile test for the -fsized-deallocation flag. This is needed
    288         # in test/std/language.support/support.dynamic/new.delete
    289         if self.cxx.hasCompileFlag('-fsized-deallocation'):
    290             self.config.available_features.add('fsized-deallocation')
    291 
    292     def configure_compile_flags(self):
    293         no_default_flags = self.get_lit_bool('no_default_flags', False)
    294         if not no_default_flags:
    295             self.configure_default_compile_flags()
    296         # This include is always needed so add so add it regardless of
    297         # 'no_default_flags'.
    298         support_path = os.path.join(self.libcxx_src_root, 'test/support')
    299         self.cxx.compile_flags += ['-I' + support_path]
    300         # Configure extra flags
    301         compile_flags_str = self.get_lit_conf('compile_flags', '')
    302         self.cxx.compile_flags += shlex.split(compile_flags_str)
    303 
    304     def configure_default_compile_flags(self):
    305         # Try and get the std version from the command line. Fall back to
    306         # default given in lit.site.cfg is not present. If default is not
    307         # present then force c++11.
    308         std = self.get_lit_conf('std')
    309         if not std:
    310             # Choose the newest possible language dialect if none is given.
    311             possible_stds = ['c++1z', 'c++14', 'c++11', 'c++03']
    312             for s in possible_stds:
    313                 if self.cxx.hasCompileFlag('-std=%s' % s):
    314                     std = s
    315                     self.lit_config.note(
    316                         'inferred language dialect as: %s' % std)
    317                     break
    318             if not std:
    319                 self.lit_config.fatal(
    320                     'Failed to infer a supported language dialect from one of %r'
    321                     % possible_stds)
    322         self.cxx.compile_flags += ['-std={0}'.format(std)]
    323         self.config.available_features.add(std)
    324         # Configure include paths
    325         self.cxx.compile_flags += ['-nostdinc++']
    326         self.configure_compile_flags_header_includes()
    327         self.target_info.add_cxx_compile_flags(self.cxx.compile_flags)
    328         # Configure feature flags.
    329         self.configure_compile_flags_exceptions()
    330         self.configure_compile_flags_rtti()
    331         self.configure_compile_flags_abi_version()
    332         enable_32bit = self.get_lit_bool('enable_32bit', False)
    333         if enable_32bit:
    334             self.cxx.flags += ['-m32']
    335         # Use verbose output for better errors
    336         self.cxx.flags += ['-v']
    337         sysroot = self.get_lit_conf('sysroot')
    338         if sysroot:
    339             self.cxx.flags += ['--sysroot', sysroot]
    340         gcc_toolchain = self.get_lit_conf('gcc_toolchain')
    341         if gcc_toolchain:
    342             self.cxx.flags += ['-gcc-toolchain', gcc_toolchain]
    343         if self.use_target:
    344             self.cxx.flags += ['-target', self.config.target_triple]
    345 
    346     def configure_compile_flags_header_includes(self):
    347         support_path = os.path.join(self.libcxx_src_root, 'test/support')
    348         self.cxx.compile_flags += ['-include', os.path.join(support_path, 'nasty_macros.hpp')]
    349         self.configure_config_site_header()
    350         libcxx_headers = self.get_lit_conf(
    351             'libcxx_headers', os.path.join(self.libcxx_src_root, 'include'))
    352         if not os.path.isdir(libcxx_headers):
    353             self.lit_config.fatal("libcxx_headers='%s' is not a directory."
    354                                   % libcxx_headers)
    355         self.cxx.compile_flags += ['-I' + libcxx_headers]
    356 
    357     def configure_config_site_header(self):
    358         # Check for a possible __config_site in the build directory. We
    359         # use this if it exists.
    360         if self.libcxx_obj_root is None:
    361             return
    362         config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
    363         if not os.path.isfile(config_site_header):
    364             return
    365         contained_macros = self.parse_config_site_and_add_features(
    366             config_site_header)
    367         self.lit_config.note('Using __config_site header %s with macros: %r'
    368             % (config_site_header, contained_macros))
    369         # FIXME: This must come after the call to
    370         # 'parse_config_site_and_add_features(...)' in order for it to work.
    371         self.cxx.compile_flags += ['-include', config_site_header]
    372 
    373     def parse_config_site_and_add_features(self, header):
    374         """ parse_config_site_and_add_features - Deduce and add the test
    375             features that that are implied by the #define's in the __config_site
    376             header. Return a dictionary containing the macros found in the
    377             '__config_site' header.
    378         """
    379         # Parse the macro contents of __config_site by dumping the macros
    380         # using 'c++ -dM -E' and filtering the predefines.
    381         predefines = self.cxx.dumpMacros()
    382         macros = self.cxx.dumpMacros(header)
    383         feature_macros_keys = set(macros.keys()) - set(predefines.keys())
    384         feature_macros = {}
    385         for k in feature_macros_keys:
    386             feature_macros[k] = macros[k]
    387         # We expect the header guard to be one of the definitions
    388         assert '_LIBCPP_CONFIG_SITE' in feature_macros
    389         del feature_macros['_LIBCPP_CONFIG_SITE']
    390         # The __config_site header should be non-empty. Otherwise it should
    391         # have never been emitted by CMake.
    392         assert len(feature_macros) > 0
    393         # Transform each macro name into the feature name used in the tests.
    394         # Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
    395         for m in feature_macros:
    396             if m == '_LIBCPP_ABI_VERSION':
    397                 self.config.available_features.add('libcpp-abi-version-v%s'
    398                     % feature_macros[m])
    399                 continue
    400             assert m.startswith('_LIBCPP_HAS_') or m == '_LIBCPP_ABI_UNSTABLE'
    401             m = m.lower()[1:].replace('_', '-')
    402             self.config.available_features.add(m)
    403         return feature_macros
    404 
    405 
    406 
    407     def configure_compile_flags_exceptions(self):
    408         enable_exceptions = self.get_lit_bool('enable_exceptions', True)
    409         if not enable_exceptions:
    410             self.config.available_features.add('libcpp-no-exceptions')
    411             self.cxx.compile_flags += ['-fno-exceptions']
    412 
    413     def configure_compile_flags_rtti(self):
    414         enable_rtti = self.get_lit_bool('enable_rtti', True)
    415         if not enable_rtti:
    416             self.config.available_features.add('libcpp-no-rtti')
    417             self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
    418 
    419     def configure_compile_flags_abi_version(self):
    420         abi_version = self.get_lit_conf('abi_version', '').strip()
    421         abi_unstable = self.get_lit_bool('abi_unstable')
    422         # Only add the ABI version when it is non-default.
    423         # FIXME(EricWF): Get the ABI version from the "__config_site".
    424         if abi_version and abi_version != '1':
    425           self.cxx.compile_flags += ['-D_LIBCPP_ABI_VERSION=' + abi_version]
    426         if abi_unstable:
    427           self.config.available_features.add('libcpp-abi-unstable')
    428           self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
    429 
    430     def configure_link_flags(self):
    431         no_default_flags = self.get_lit_bool('no_default_flags', False)
    432         if not no_default_flags:
    433             self.cxx.link_flags += ['-nodefaultlibs']
    434 
    435             # Configure library path
    436             self.configure_link_flags_cxx_library_path()
    437             self.configure_link_flags_abi_library_path()
    438 
    439             # Configure libraries
    440             self.configure_link_flags_cxx_library()
    441             self.configure_link_flags_abi_library()
    442             self.configure_extra_library_flags()
    443 
    444         link_flags_str = self.get_lit_conf('link_flags', '')
    445         self.cxx.link_flags += shlex.split(link_flags_str)
    446 
    447     def configure_link_flags_cxx_library_path(self):
    448         if not self.use_system_cxx_lib:
    449             if self.cxx_library_root:
    450                 self.cxx.link_flags += ['-L' + self.cxx_library_root]
    451             if self.cxx_runtime_root:
    452                 self.cxx.link_flags += ['-Wl,-rpath,' + self.cxx_runtime_root]
    453 
    454     def configure_link_flags_abi_library_path(self):
    455         # Configure ABI library paths.
    456         self.abi_library_root = self.get_lit_conf('abi_library_path')
    457         if self.abi_library_root:
    458             self.cxx.link_flags += ['-L' + self.abi_library_root,
    459                                     '-Wl,-rpath,' + self.abi_library_root]
    460 
    461     def configure_link_flags_cxx_library(self):
    462         libcxx_experimental = self.get_lit_bool('enable_experimental', default=False)
    463         if libcxx_experimental:
    464             self.config.available_features.add('c++experimental')
    465             self.cxx.link_flags += ['-lc++experimental']
    466         libcxx_shared = self.get_lit_bool('enable_shared', default=True)
    467         if libcxx_shared:
    468             self.cxx.link_flags += ['-lc++']
    469         else:
    470             cxx_library_root = self.get_lit_conf('cxx_library_root')
    471             if cxx_library_root:
    472                 abs_path = os.path.join(cxx_library_root, 'libc++.a')
    473                 self.cxx.link_flags += [abs_path]
    474             else:
    475                 self.cxx.link_flags += ['-lc++']
    476 
    477     def configure_link_flags_abi_library(self):
    478         cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
    479         if cxx_abi == 'libstdc++':
    480             self.cxx.link_flags += ['-lstdc++']
    481         elif cxx_abi == 'libsupc++':
    482             self.cxx.link_flags += ['-lsupc++']
    483         elif cxx_abi == 'libcxxabi':
    484             if self.target_info.allow_cxxabi_link():
    485                 libcxxabi_shared = self.get_lit_bool('libcxxabi_shared', default=True)
    486                 if libcxxabi_shared:
    487                     self.cxx.link_flags += ['-lc++abi']
    488                 else:
    489                     cxxabi_library_root = self.get_lit_conf('abi_library_path')
    490                     if cxxabi_library_root:
    491                         abs_path = os.path.join(cxxabi_library_root, 'libc++abi.a')
    492                         self.cxx.link_flags += [abs_path]
    493                     else:
    494                         self.cxx.link_flags += ['-lc++abi']
    495         elif cxx_abi == 'libcxxrt':
    496             self.cxx.link_flags += ['-lcxxrt']
    497         elif cxx_abi == 'none':
    498             pass
    499         else:
    500             self.lit_config.fatal(
    501                 'C++ ABI setting %s unsupported for tests' % cxx_abi)
    502 
    503     def configure_extra_library_flags(self):
    504         self.target_info.add_cxx_link_flags(self.cxx.link_flags)
    505 
    506     def configure_color_diagnostics(self):
    507         use_color = self.get_lit_conf('color_diagnostics')
    508         if use_color is None:
    509             use_color = os.environ.get('LIBCXX_COLOR_DIAGNOSTICS')
    510         if use_color is None:
    511             return
    512         if use_color != '':
    513             self.lit_config.fatal('Invalid value for color_diagnostics "%s".'
    514                                   % use_color)
    515         color_flag = '-fdiagnostics-color=always'
    516         # Check if the compiler supports the color diagnostics flag. Issue a
    517         # warning if it does not since color diagnostics have been requested.
    518         if not self.cxx.hasCompileFlag(color_flag):
    519             self.lit_config.warning(
    520                 'color diagnostics have been requested but are not supported '
    521                 'by the compiler')
    522         else:
    523             self.cxx.flags += [color_flag]
    524 
    525     def configure_debug_mode(self):
    526         debug_level = self.get_lit_conf('debug_level', None)
    527         if not debug_level:
    528             return
    529         if debug_level not in ['0', '1']:
    530             self.lit_config.fatal('Invalid value for debug_level "%s".'
    531                                   % debug_level)
    532         self.cxx.compile_flags += ['-D_LIBCPP_DEBUG=%s' % debug_level]
    533 
    534     def configure_warnings(self):
    535         enable_warnings = self.get_lit_bool('enable_warnings', False)
    536         if enable_warnings:
    537             self.cxx.compile_flags += [
    538                 '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER',
    539                 '-Wall', '-Wextra', '-Werror'
    540             ]
    541             self.cxx.addWarningFlagIfSupported('-Wno-attributes')
    542             self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move')
    543             self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions')
    544             self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals')
    545             # TODO(EricWF) Remove the unused warnings once the test suite
    546             # compiles clean with them.
    547             self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
    548             self.cxx.addWarningFlagIfSupported('-Wno-unused-variable')
    549             self.cxx.addWarningFlagIfSupported('-Wno-unused-parameter')
    550             self.cxx.addWarningFlagIfSupported('-Wno-sign-compare')
    551             std = self.get_lit_conf('std', None)
    552             if std in ['c++98', 'c++03']:
    553                 # The '#define static_assert' provided by libc++ in C++03 mode
    554                 # causes an unused local typedef whenever it is used.
    555                 self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
    556 
    557     def configure_sanitizer(self):
    558         san = self.get_lit_conf('use_sanitizer', '').strip()
    559         if san:
    560             self.target_info.add_sanitizer_features(san, self.config.available_features)
    561             # Search for llvm-symbolizer along the compiler path first
    562             # and then along the PATH env variable.
    563             symbolizer_search_paths = os.environ.get('PATH', '')
    564             cxx_path = lit.util.which(self.cxx.path)
    565             if cxx_path is not None:
    566                 symbolizer_search_paths = (
    567                     os.path.dirname(cxx_path) +
    568                     os.pathsep + symbolizer_search_paths)
    569             llvm_symbolizer = lit.util.which('llvm-symbolizer',
    570                                              symbolizer_search_paths)
    571             # Setup the sanitizer compile flags
    572             self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
    573             if san == 'Address':
    574                 self.cxx.flags += ['-fsanitize=address']
    575                 if llvm_symbolizer is not None:
    576                     self.env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
    577                 self.config.available_features.add('asan')
    578                 self.config.available_features.add('sanitizer-new-delete')
    579             elif san == 'Memory' or san == 'MemoryWithOrigins':
    580                 self.cxx.flags += ['-fsanitize=memory']
    581                 if san == 'MemoryWithOrigins':
    582                     self.cxx.compile_flags += [
    583                         '-fsanitize-memory-track-origins']
    584                 if llvm_symbolizer is not None:
    585                     self.env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
    586                 self.config.available_features.add('msan')
    587                 self.config.available_features.add('sanitizer-new-delete')
    588             elif san == 'Undefined':
    589                 self.cxx.flags += ['-fsanitize=undefined',
    590                                    '-fno-sanitize=vptr,function',
    591                                    '-fno-sanitize-recover']
    592                 self.cxx.compile_flags += ['-O3']
    593                 self.env['UBSAN_OPTIONS'] = 'print_stacktrace=1'
    594                 self.config.available_features.add('ubsan')
    595             elif san == 'Thread':
    596                 self.cxx.flags += ['-fsanitize=thread']
    597                 self.config.available_features.add('tsan')
    598                 self.config.available_features.add('sanitizer-new-delete')
    599             else:
    600                 self.lit_config.fatal('unsupported value for '
    601                                       'use_sanitizer: {0}'.format(san))
    602             san_lib = self.get_lit_conf('sanitizer_library')
    603             if san_lib:
    604                 self.cxx.link_flags += [
    605                     san_lib, '-Wl,-rpath,%s' % os.path.dirname(san_lib)]
    606 
    607     def configure_coverage(self):
    608         self.generate_coverage = self.get_lit_bool('generate_coverage', False)
    609         if self.generate_coverage:
    610             self.cxx.flags += ['-g', '--coverage']
    611             self.cxx.compile_flags += ['-O0']
    612 
    613     def configure_substitutions(self):
    614         sub = self.config.substitutions
    615         # Configure compiler substitions
    616         sub.append(('%cxx', self.cxx.path))
    617         # Configure flags substitutions
    618         flags_str = ' '.join(self.cxx.flags)
    619         compile_flags_str = ' '.join(self.cxx.compile_flags)
    620         link_flags_str = ' '.join(self.cxx.link_flags)
    621         all_flags = '%s %s %s' % (flags_str, compile_flags_str, link_flags_str)
    622         sub.append(('%flags', flags_str))
    623         sub.append(('%compile_flags', compile_flags_str))
    624         sub.append(('%link_flags', link_flags_str))
    625         sub.append(('%all_flags', all_flags))
    626         # Add compile and link shortcuts
    627         compile_str = (self.cxx.path + ' -o %t.o %s -c ' + flags_str
    628                        + compile_flags_str)
    629         link_str = (self.cxx.path + ' -o %t.exe %t.o ' + flags_str
    630                     + link_flags_str)
    631         assert type(link_str) is str
    632         build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
    633         sub.append(('%compile', compile_str))
    634         sub.append(('%link', link_str))
    635         sub.append(('%build', build_str))
    636         # Configure exec prefix substitutions.
    637         exec_env_str = 'env ' if len(self.env) != 0 else ''
    638         for k, v in self.env.items():
    639             exec_env_str += ' %s=%s' % (k, v)
    640         # Configure run env substitution.
    641         exec_str = exec_env_str
    642         if self.lit_config.useValgrind:
    643             exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
    644         sub.append(('%exec', exec_str))
    645         # Configure run shortcut
    646         sub.append(('%run', exec_str + ' %t.exe'))
    647         # Configure not program substitions
    648         not_py = os.path.join(self.libcxx_src_root, 'utils', 'not', 'not.py')
    649         not_str = '%s %s' % (sys.executable, not_py)
    650         sub.append(('not', not_str))
    651 
    652     def configure_triple(self):
    653         # Get or infer the target triple.
    654         self.config.target_triple = self.get_lit_conf('target_triple')
    655         self.use_target = bool(self.config.target_triple)
    656         # If no target triple was given, try to infer it from the compiler
    657         # under test.
    658         if not self.use_target:
    659             target_triple = self.cxx.getTriple()
    660             # Drop sub-major version components from the triple, because the
    661             # current XFAIL handling expects exact matches for feature checks.
    662             # Example: x86_64-apple-darwin14.0.0 -> x86_64-apple-darwin14
    663             # The 5th group handles triples greater than 3 parts
    664             # (ex x86_64-pc-linux-gnu).
    665             target_triple = re.sub(r'([^-]+)-([^-]+)-([^.]+)([^-]*)(.*)',
    666                                    r'\1-\2-\3\5', target_triple)
    667             # linux-gnu is needed in the triple to properly identify linuxes
    668             # that use GLIBC. Handle redhat and opensuse triples as special
    669             # cases and append the missing `-gnu` portion.
    670             if (target_triple.endswith('redhat-linux') or
    671                 target_triple.endswith('suse-linux')):
    672                 target_triple += '-gnu'
    673             self.config.target_triple = target_triple
    674             self.lit_config.note(
    675                 "inferred target_triple as: %r" % self.config.target_triple)
    676 
    677     def configure_env(self):
    678         self.target_info.configure_env(self.env)
    679