1# -*- Python -*- 2 3import os 4import platform 5import re 6import shlex 7 8import lit.formats 9 10 11def get_required_attr(config, attr_name): 12 attr_value = getattr(config, attr_name, None) 13 if attr_value is not None: 14 return attr_value 15 16 lit_config.fatal( 17 "No attribute %r in test configuration! You may need to run " 18 "tests from your build directory or add this attribute " 19 "to lit.site.cfg.py " % attr_name 20 ) 21 22 23def push_dynamic_library_lookup_path(config, new_path): 24 if platform.system() == "Windows": 25 dynamic_library_lookup_var = "PATH" 26 elif platform.system() == "Darwin": 27 dynamic_library_lookup_var = "DYLD_LIBRARY_PATH" 28 else: 29 dynamic_library_lookup_var = "LD_LIBRARY_PATH" 30 31 new_ld_library_path = os.path.pathsep.join( 32 (new_path, config.environment.get(dynamic_library_lookup_var, "")) 33 ) 34 config.environment[dynamic_library_lookup_var] = new_ld_library_path 35 36 if platform.system() == "FreeBSD": 37 dynamic_library_lookup_var = "LD_32_LIBRARY_PATH" 38 new_ld_32_library_path = os.path.pathsep.join( 39 (new_path, config.environment.get(dynamic_library_lookup_var, "")) 40 ) 41 config.environment[dynamic_library_lookup_var] = new_ld_32_library_path 42 43 if platform.system() == "SunOS": 44 dynamic_library_lookup_var = "LD_LIBRARY_PATH_32" 45 new_ld_library_path_32 = os.path.pathsep.join( 46 (new_path, config.environment.get(dynamic_library_lookup_var, "")) 47 ) 48 config.environment[dynamic_library_lookup_var] = new_ld_library_path_32 49 50 dynamic_library_lookup_var = "LD_LIBRARY_PATH_64" 51 new_ld_library_path_64 = os.path.pathsep.join( 52 (new_path, config.environment.get(dynamic_library_lookup_var, "")) 53 ) 54 config.environment[dynamic_library_lookup_var] = new_ld_library_path_64 55 56 57# Setup config name. 58config.name = "TypeSanitizer" + config.name_suffix 59 60# Platform-specific default TYSAN_OPTIONS for lit tests. 61default_tysan_opts = list(config.default_sanitizer_opts) 62 63default_tysan_opts_str = ":".join(default_tysan_opts) 64if default_tysan_opts_str: 65 config.environment["TYSAN_OPTIONS"] = default_tysan_opts_str 66 default_tysan_opts_str += ":" 67config.substitutions.append( 68 ("%env_tysan_opts=", "env TYSAN_OPTIONS=" + default_tysan_opts_str) 69) 70 71# Setup source root. 72config.test_source_root = os.path.dirname(__file__) 73 74if config.host_os not in ["FreeBSD", "NetBSD"]: 75 libdl_flag = "-ldl" 76else: 77 libdl_flag = "" 78 79# GCC-ASan doesn't link in all the necessary libraries automatically, so 80# we have to do it ourselves. 81if config.compiler_id == "GNU": 82 extra_link_flags = ["-pthread", "-lstdc++", libdl_flag] 83else: 84 extra_link_flags = [] 85 86# Setup default compiler flags used with -fsanitize=address option. 87# FIXME: Review the set of required flags and check if it can be reduced. 88target_cflags = [get_required_attr(config, "target_cflags")] + extra_link_flags 89target_cxxflags = config.cxx_mode_flags + target_cflags 90clang_tysan_static_cflags = ( 91 [ 92 "-fsanitize=type", 93 "-mno-omit-leaf-frame-pointer", 94 "-fno-omit-frame-pointer", 95 "-fno-optimize-sibling-calls", 96 ] 97 + config.debug_info_flags 98 + target_cflags 99) 100if config.target_arch == "s390x": 101 clang_tysan_static_cflags.append("-mbackchain") 102clang_tysan_static_cxxflags = config.cxx_mode_flags + clang_tysan_static_cflags 103 104clang_tysan_cflags = clang_tysan_static_cflags 105clang_tysan_cxxflags = clang_tysan_static_cxxflags 106 107 108def build_invocation(compile_flags): 109 return " " + " ".join([config.clang] + compile_flags) + " " 110 111 112config.substitutions.append(("%clang ", build_invocation(target_cflags))) 113config.substitutions.append(("%clangxx ", build_invocation(target_cxxflags))) 114config.substitutions.append(("%clang_tysan ", build_invocation(clang_tysan_cflags))) 115config.substitutions.append(("%clangxx_tysan ", build_invocation(clang_tysan_cxxflags))) 116 117 118# FIXME: De-hardcode this path. 119tysan_source_dir = os.path.join( 120 get_required_attr(config, "compiler_rt_src_root"), "lib", "tysan" 121) 122python_exec = shlex.quote(get_required_attr(config, "python_executable")) 123 124# Set LD_LIBRARY_PATH to pick dynamic runtime up properly. 125push_dynamic_library_lookup_path(config, config.compiler_rt_libdir) 126 127# Default test suffixes. 128config.suffixes = [".c", ".cpp"] 129 130if config.host_os == "Darwin": 131 config.suffixes.append(".mm") 132 133if config.host_os == "Windows": 134 config.substitutions.append(("%fPIC", "")) 135 config.substitutions.append(("%fPIE", "")) 136 config.substitutions.append(("%pie", "")) 137else: 138 config.substitutions.append(("%fPIC", "-fPIC")) 139 config.substitutions.append(("%fPIE", "-fPIE")) 140 config.substitutions.append(("%pie", "-pie")) 141 142# Only run the tests on supported OSs. 143if config.host_os not in [ 144 "Linux", 145 "Darwin", 146]: 147 config.unsupported = Tr 148