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 10import locale 11import os 12import platform 13import pkgutil 14import re 15import shlex 16import sys 17 18import lit.Test # pylint: disable=import-error,no-name-in-module 19import lit.util # pylint: disable=import-error,no-name-in-module 20 21from libcxx.test.format import LibcxxTestFormat 22from libcxx.compiler import CXXCompiler 23from libcxx.test.target_info import make_target_info 24from libcxx.test.executor import * 25from libcxx.test.tracing import * 26 27def 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 54class 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