Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / test / asan / lit.cfg.py
blobd93034660212509c599b83be12601ee95b32a762
1 # -*- Python -*-
3 import os
4 import platform
5 import re
6 import shlex
8 import lit.formats
11 def get_required_attr(config, attr_name):
12 attr_value = getattr(config, attr_name, None)
13 if attr_value == None:
14 lit_config.fatal(
15 "No attribute %r in test configuration! You may need to run "
16 "tests from your build directory or add this attribute "
17 "to lit.site.cfg.py " % attr_name
19 return attr_value
21 # Setup config name.
22 config.name = "AddressSanitizer" + config.name_suffix
24 # Platform-specific default ASAN_OPTIONS for lit tests.
25 default_asan_opts = list(config.default_sanitizer_opts)
27 # On Darwin, leak checking is not enabled by default. Enable on macOS
28 # tests to prevent regressions
29 if config.host_os == "Darwin" and config.apple_platform == "osx":
30 default_asan_opts += ["detect_leaks=1"]
32 default_asan_opts_str = ":".join(default_asan_opts)
33 if default_asan_opts_str:
34 config.environment["ASAN_OPTIONS"] = default_asan_opts_str
35 default_asan_opts_str += ":"
36 config.substitutions.append(
37 ("%env_asan_opts=", "env ASAN_OPTIONS=" + default_asan_opts_str)
40 # Setup source root.
41 config.test_source_root = os.path.dirname(__file__)
43 if config.host_os not in ["FreeBSD", "NetBSD"]:
44 libdl_flag = "-ldl"
45 else:
46 libdl_flag = ""
48 # GCC-ASan doesn't link in all the necessary libraries automatically, so
49 # we have to do it ourselves.
50 if config.compiler_id == "GNU":
51 extra_link_flags = ["-pthread", "-lstdc++", libdl_flag]
52 else:
53 extra_link_flags = []
55 # Setup default compiler flags used with -fsanitize=address option.
56 # FIXME: Review the set of required flags and check if it can be reduced.
57 target_cflags = [get_required_attr(config, "target_cflags")] + extra_link_flags
58 target_cxxflags = config.cxx_mode_flags + target_cflags
59 clang_asan_static_cflags = (
61 "-fsanitize=address",
62 "-mno-omit-leaf-frame-pointer",
63 "-fno-omit-frame-pointer",
64 "-fno-optimize-sibling-calls",
66 + config.debug_info_flags
67 + target_cflags
69 if config.target_arch == "s390x":
70 clang_asan_static_cflags.append("-mbackchain")
71 clang_asan_static_cxxflags = config.cxx_mode_flags + clang_asan_static_cflags
73 target_is_msvc = bool(re.match(r".*-windows-msvc$", config.target_triple))
75 asan_dynamic_flags = []
76 if config.asan_dynamic:
77 asan_dynamic_flags = ["-shared-libasan"]
78 if platform.system() == "Windows" and target_is_msvc:
79 # On MSVC target, we need to simulate "clang-cl /MD" on the clang driver side.
80 asan_dynamic_flags += [
81 "-D_MT",
82 "-D_DLL",
83 "-Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames",
85 elif platform.system() == "FreeBSD":
86 # On FreeBSD, we need to add -pthread to ensure pthread functions are available.
87 asan_dynamic_flags += ["-pthread"]
88 config.available_features.add("asan-dynamic-runtime")
89 else:
90 config.available_features.add("asan-static-runtime")
91 clang_asan_cflags = clang_asan_static_cflags + asan_dynamic_flags
92 clang_asan_cxxflags = clang_asan_static_cxxflags + asan_dynamic_flags
94 # Add win32-(static|dynamic)-asan features to mark tests as passing or failing
95 # in those modes. lit doesn't support logical feature test combinations.
96 if platform.system() == "Windows":
97 if config.asan_dynamic:
98 win_runtime_feature = "win32-dynamic-asan"
99 else:
100 win_runtime_feature = "win32-static-asan"
101 config.available_features.add(win_runtime_feature)
104 def build_invocation(compile_flags):
105 return " " + " ".join([config.clang] + compile_flags) + " "
108 config.substitutions.append(("%clang ", build_invocation(target_cflags)))
109 config.substitutions.append(("%clangxx ", build_invocation(target_cxxflags)))
110 config.substitutions.append(("%clang_asan ", build_invocation(clang_asan_cflags)))
111 config.substitutions.append(("%clangxx_asan ", build_invocation(clang_asan_cxxflags)))
112 if config.asan_dynamic:
113 if config.host_os in ["Linux", "FreeBSD", "NetBSD", "SunOS"]:
114 shared_libasan_path = os.path.join(
115 config.compiler_rt_libdir,
116 "libclang_rt.asan{}.so".format(config.target_suffix),
118 elif config.host_os == "Darwin":
119 shared_libasan_path = os.path.join(
120 config.compiler_rt_libdir,
121 "libclang_rt.asan_{}_dynamic.dylib".format(config.apple_platform),
123 else:
124 lit_config.warning(
125 "%shared_libasan substitution not set but dynamic ASan is available."
127 shared_libasan_path = None
129 if shared_libasan_path is not None:
130 config.substitutions.append(("%shared_libasan", shared_libasan_path))
131 config.substitutions.append(
132 ("%clang_asan_static ", build_invocation(clang_asan_static_cflags))
134 config.substitutions.append(
135 ("%clangxx_asan_static ", build_invocation(clang_asan_static_cxxflags))
138 if platform.system() == "Windows":
139 # MSVC-specific tests might also use the clang-cl.exe driver.
140 if target_is_msvc:
141 clang_cl_cxxflags = [
142 "-Wno-deprecated-declarations",
143 "-WX",
144 "-D_HAS_EXCEPTIONS=0",
145 "-Zi",
146 ] + target_cflags
147 clang_cl_asan_cxxflags = ["-fsanitize=address"] + clang_cl_cxxflags
148 if config.asan_dynamic:
149 clang_cl_asan_cxxflags.append("-MD")
151 clang_cl_invocation = build_invocation(clang_cl_cxxflags)
152 clang_cl_invocation = clang_cl_invocation.replace("clang.exe", "clang-cl.exe")
153 config.substitutions.append(("%clang_cl ", clang_cl_invocation))
155 clang_cl_asan_invocation = build_invocation(clang_cl_asan_cxxflags)
156 clang_cl_asan_invocation = clang_cl_asan_invocation.replace(
157 "clang.exe", "clang-cl.exe"
159 config.substitutions.append(("%clang_cl_asan ", clang_cl_asan_invocation))
160 config.substitutions.append(("%clang_cl_nocxx_asan ", clang_cl_asan_invocation))
161 config.substitutions.append(("%Od", "-Od"))
162 config.substitutions.append(("%Fe", "-Fe"))
163 config.substitutions.append(("%LD", "-LD"))
164 config.substitutions.append(("%MD", "-MD"))
165 config.substitutions.append(("%MT", "-MT"))
166 config.substitutions.append(("%Gw", "-Gw"))
168 base_lib = os.path.join(
169 config.compiler_rt_libdir, "clang_rt.asan%%s%s.lib" % config.target_suffix
171 config.substitutions.append(("%asan_lib", base_lib % ""))
172 config.substitutions.append(("%asan_cxx_lib", base_lib % "_cxx"))
173 config.substitutions.append(("%asan_dll_thunk", base_lib % "_dll_thunk"))
174 else:
175 # To make some of these tests work on MinGW target without changing their
176 # behaviour for MSVC target, substitute clang-cl flags with gcc-like ones.
177 config.substitutions.append(("%clang_cl ", build_invocation(target_cxxflags)))
178 config.substitutions.append(
179 ("%clang_cl_asan ", build_invocation(clang_asan_cxxflags))
181 config.substitutions.append(
182 ("%clang_cl_nocxx_asan ", build_invocation(clang_asan_cflags))
184 config.substitutions.append(("%Od", "-O0"))
185 config.substitutions.append(("%Fe", "-o"))
186 config.substitutions.append(("%LD", "-shared"))
187 config.substitutions.append(("%MD", ""))
188 config.substitutions.append(("%MT", ""))
189 config.substitutions.append(("%Gw", "-fdata-sections"))
191 # FIXME: De-hardcode this path.
192 asan_source_dir = os.path.join(
193 get_required_attr(config, "compiler_rt_src_root"), "lib", "asan"
195 python_exec = shlex.quote(get_required_attr(config, "python_executable"))
196 # Setup path to asan_symbolize.py script.
197 asan_symbolize = os.path.join(asan_source_dir, "scripts", "asan_symbolize.py")
198 if not os.path.exists(asan_symbolize):
199 lit_config.fatal("Can't find script on path %r" % asan_symbolize)
200 config.substitutions.append(
201 ("%asan_symbolize", python_exec + " " + asan_symbolize + " ")
203 # Setup path to sancov.py script.
204 sanitizer_common_source_dir = os.path.join(
205 get_required_attr(config, "compiler_rt_src_root"), "lib", "sanitizer_common"
207 sancov = os.path.join(sanitizer_common_source_dir, "scripts", "sancov.py")
208 if not os.path.exists(sancov):
209 lit_config.fatal("Can't find script on path %r" % sancov)
210 config.substitutions.append(("%sancov ", python_exec + " " + sancov + " "))
212 # Determine kernel bitness
213 if config.host_arch.find("64") != -1 and not config.android:
214 kernel_bits = "64"
215 else:
216 kernel_bits = "32"
218 config.substitutions.append(
219 ("CHECK-%kernel_bits", ("CHECK-kernel-" + kernel_bits + "-bits"))
222 config.substitutions.append(("%libdl", libdl_flag))
224 config.available_features.add("asan-" + config.bits + "-bits")
226 # Fast unwinder doesn't work with Thumb
227 if not config.arm_thumb:
228 config.available_features.add("fast-unwinder-works")
230 # Turn on leak detection on 64-bit Linux.
231 leak_detection_android = (
232 config.android
233 and "android-thread-properties-api" in config.available_features
234 and (config.target_arch in ["x86_64", "i386", "i686", "aarch64"])
236 leak_detection_linux = (
237 (config.host_os == "Linux")
238 and (not config.android)
239 and (config.target_arch in ["x86_64", "i386", "riscv64", "loongarch64"])
241 leak_detection_mac = (config.host_os == "Darwin") and (config.apple_platform == "osx")
242 leak_detection_netbsd = (config.host_os == "NetBSD") and (
243 config.target_arch in ["x86_64", "i386"]
245 if (
246 leak_detection_android
247 or leak_detection_linux
248 or leak_detection_mac
249 or leak_detection_netbsd
251 config.available_features.add("leak-detection")
253 # Add the RT libdir to PATH directly so that we can successfully run the gtest
254 # binary to list its tests.
255 if config.host_os == "Windows" and config.asan_dynamic:
256 os.environ["PATH"] = os.path.pathsep.join(
257 [config.compiler_rt_libdir, os.environ.get("PATH", "")]
260 # Default test suffixes.
261 config.suffixes = [".c", ".cpp"]
263 if config.host_os == "Darwin":
264 config.suffixes.append(".mm")
266 if config.host_os == "Windows":
267 config.substitutions.append(("%fPIC", ""))
268 config.substitutions.append(("%fPIE", ""))
269 config.substitutions.append(("%pie", ""))
270 else:
271 config.substitutions.append(("%fPIC", "-fPIC"))
272 config.substitutions.append(("%fPIE", "-fPIE"))
273 config.substitutions.append(("%pie", "-pie"))
275 # Only run the tests on supported OSs.
276 if config.host_os not in ["Linux", "Darwin", "FreeBSD", "SunOS", "Windows", "NetBSD"]:
277 config.unsupported = True
279 if not config.parallelism_group:
280 config.parallelism_group = "shadow-memory"
282 if config.host_os == "NetBSD":
283 config.substitutions.insert(0, ("%run", config.netbsd_noaslr_prefix))