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