blob: 475e78c226282ca6aa2378f92198f8d7df33d1b0 [file] [log] [blame]
Daniel Dunbar3bc6a982013-02-12 19:28:51 +00001# -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=80:
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +00002
3# Configuration file for the 'lit' test runner.
4
Daniel Dunbar9e9d0762013-08-30 19:52:12 +00005import errno
Dan Albertb4ed5ca2014-08-04 18:44:48 +00006import locale
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +00007import os
8import platform
Daniel Dunbar9e9d0762013-08-30 19:52:12 +00009import re
10import shlex
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +000011import signal
12import subprocess
Daniel Dunbar9e9d0762013-08-30 19:52:12 +000013import sys
14import tempfile
Howard Hinnantb4ebb0e2013-01-14 17:12:54 +000015import time
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +000016
Daniel Dunbarbd7b48a2013-08-09 14:44:11 +000017import lit.Test
18import lit.formats
19import lit.util
20
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +000021class LibcxxTestFormat(lit.formats.FileBasedTest):
22 """
23 Custom test format handler for use with the test format use by libc++.
24
25 Tests fall into two categories:
26 FOO.pass.cpp - Executable test which should compile, run, and exit with
27 code 0.
28 FOO.fail.cpp - Negative test case which is expected to fail compilation.
29 """
30
Justin Bogner837cfe52014-09-03 04:32:08 +000031 def __init__(self, cxx_under_test, use_verify_for_fail,
32 cpp_flags, ld_flags, exec_env):
Daniel Dunbar7e0c57b2010-09-15 04:11:29 +000033 self.cxx_under_test = cxx_under_test
Justin Bogner837cfe52014-09-03 04:32:08 +000034 self.use_verify_for_fail = use_verify_for_fail
Daniel Dunbar611581b2010-09-15 04:31:58 +000035 self.cpp_flags = list(cpp_flags)
36 self.ld_flags = list(ld_flags)
Daniel Dunbarcccf2552013-02-05 18:03:49 +000037 self.exec_env = dict(exec_env)
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +000038
Howard Hinnantb4ebb0e2013-01-14 17:12:54 +000039 def execute_command(self, command, in_dir=None):
40 kwargs = {
41 'stdin' :subprocess.PIPE,
42 'stdout':subprocess.PIPE,
43 'stderr':subprocess.PIPE,
44 }
45 if in_dir:
46 kwargs['cwd'] = in_dir
47 p = subprocess.Popen(command, **kwargs)
Dan Albert877409a2014-11-24 22:24:06 +000048 out, err = p.communicate()
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +000049 exitCode = p.wait()
50
51 # Detect Ctrl-C in subprocess.
52 if exitCode == -signal.SIGINT:
53 raise KeyboardInterrupt
54
55 return out, err, exitCode
56
57 def execute(self, test, lit_config):
Howard Hinnantb4ebb0e2013-01-14 17:12:54 +000058 while True:
59 try:
60 return self._execute(test, lit_config)
61 except OSError, oe:
62 if oe.errno != errno.ETXTBSY:
63 raise
64 time.sleep(0.1)
65
66 def _execute(self, test, lit_config):
Daniel Dunbar81d1ef72013-02-05 21:03:25 +000067 # Extract test metadata from the test file.
Daniel Dunbar81d1ef72013-02-05 21:03:25 +000068 requires = []
Eric Fiselierda98ce02014-08-18 06:43:06 +000069 unsupported = []
Justin Bogner464da3b2014-09-03 06:01:52 +000070 use_verify = False
Daniel Dunbar81d1ef72013-02-05 21:03:25 +000071 with open(test.getSourcePath()) as f:
72 for ln in f:
73 if 'XFAIL:' in ln:
74 items = ln[ln.index('XFAIL:') + 6:].split(',')
Daniel Dunbar585b48d2013-08-21 23:06:32 +000075 test.xfails.extend([s.strip() for s in items])
Daniel Dunbar81d1ef72013-02-05 21:03:25 +000076 elif 'REQUIRES:' in ln:
77 items = ln[ln.index('REQUIRES:') + 9:].split(',')
78 requires.extend([s.strip() for s in items])
Eric Fiselierda98ce02014-08-18 06:43:06 +000079 elif 'UNSUPPORTED:' in ln:
80 items = ln[ln.index('UNSUPPORTED:') + 12:].split(',')
81 unsupported.extend([s.strip() for s in items])
Justin Bogner464da3b2014-09-03 06:01:52 +000082 elif 'USE_VERIFY' in ln and self.use_verify_for_fail:
83 use_verify = True
Eric Fiselierd3d01ea2014-07-31 22:56:52 +000084 elif not ln.strip().startswith("//") and ln.strip():
Daniel Dunbar81d1ef72013-02-05 21:03:25 +000085 # Stop at the first non-empty line that is not a C++
86 # comment.
87 break
88
89 # Check that we have the required features.
90 #
91 # FIXME: For now, this is cribbed from lit.TestRunner, to avoid
92 # introducing a dependency there. What we more ideally would like to do
Daniel Dunbar585b48d2013-08-21 23:06:32 +000093 # is lift the "requires" handling to be a core lit framework feature.
Daniel Dunbar81d1ef72013-02-05 21:03:25 +000094 missing_required_features = [f for f in requires
95 if f not in test.config.available_features]
96 if missing_required_features:
97 return (lit.Test.UNSUPPORTED,
98 "Test requires the following features: %s" % (
99 ', '.join(missing_required_features),))
100
Eric Fiselierda98ce02014-08-18 06:43:06 +0000101 unsupported_features = [f for f in unsupported
102 if f in test.config.available_features]
103 if unsupported_features:
104 return (lit.Test.UNSUPPORTED,
105 "Test is unsupported with the following features: %s" % (
106 ', '.join(unsupported_features),))
107
Daniel Dunbar81d1ef72013-02-05 21:03:25 +0000108 # Evaluate the test.
Justin Bogner464da3b2014-09-03 06:01:52 +0000109 return self._evaluate_test(test, use_verify, lit_config)
Daniel Dunbar81d1ef72013-02-05 21:03:25 +0000110
Dan Albert877409a2014-11-24 22:24:06 +0000111 def _build(self, exec_path, source_path, compile_only=False,
112 use_verify=False):
113 cmd = [self.cxx_under_test, '-o', exec_path,
114 source_path] + self.cpp_flags
115
116 if compile_only:
117 cmd += ['-c']
118 else:
119 cmd += self.ld_flags
120
121 if use_verify:
122 cmd += ['-Xclang', '-verify']
123
124 out, err, rc = self.execute_command(cmd)
125 return cmd, out, err, rc
126
127 def _clean(self, exec_path):
128 os.remove(exec_path)
129
130 def _run(self, exec_path, lit_config, in_dir=None):
131 cmd = []
132 if self.exec_env:
133 cmd.append('env')
134 cmd.extend('%s=%s' % (name, value)
135 for name,value in self.exec_env.items())
136 cmd.append(exec_path)
137 if lit_config.useValgrind:
138 cmd = lit_config.valgrindArgs + cmd
139 out, err, exitCode = self.execute_command(cmd, in_dir)
140 return cmd, out, err, exitCode
141
Justin Bogner464da3b2014-09-03 06:01:52 +0000142 def _evaluate_test(self, test, use_verify, lit_config):
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000143 name = test.path_in_suite[-1]
144 source_path = test.getSourcePath()
Howard Hinnantb4ebb0e2013-01-14 17:12:54 +0000145 source_dir = os.path.dirname(source_path)
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000146
147 # Check what kind of test this is.
148 assert name.endswith('.pass.cpp') or name.endswith('.fail.cpp')
149 expected_compile_fail = name.endswith('.fail.cpp')
150
151 # If this is a compile (failure) test, build it and check for failure.
152 if expected_compile_fail:
Dan Albert877409a2014-11-24 22:24:06 +0000153 cmd, out, err, rc = self._build('/dev/null', source_path,
154 compile_only=True,
155 use_verify=use_verify)
156 expected_rc = 0 if use_verify else 1
Justin Bogner837cfe52014-09-03 04:32:08 +0000157 if rc == expected_rc:
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000158 return lit.Test.PASS, ""
159 else:
160 report = """Command: %s\n""" % ' '.join(["'%s'" % a
161 for a in cmd])
Justin Bogner837cfe52014-09-03 04:32:08 +0000162 report += """Exit Code: %d\n""" % rc
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000163 if out:
164 report += """Standard Output:\n--\n%s--""" % out
165 if err:
166 report += """Standard Error:\n--\n%s--""" % err
167 report += "\n\nExpected compilation to fail!"
Daniel Dunbar611581b2010-09-15 04:31:58 +0000168 return lit.Test.FAIL, report
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000169 else:
170 exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
171 exec_path = exec_file.name
172 exec_file.close()
173
174 try:
Dan Albert877409a2014-11-24 22:24:06 +0000175 cmd, out, err, rc = self._build(exec_path, source_path)
176 compile_cmd = cmd
177 if rc != 0:
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000178 report = """Command: %s\n""" % ' '.join(["'%s'" % a
179 for a in cmd])
Dan Albert877409a2014-11-24 22:24:06 +0000180 report += """Exit Code: %d\n""" % rc
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000181 if out:
182 report += """Standard Output:\n--\n%s--""" % out
183 if err:
184 report += """Standard Error:\n--\n%s--""" % err
185 report += "\n\nCompilation failed unexpectedly!"
186 return lit.Test.FAIL, report
187
Dan Albert877409a2014-11-24 22:24:06 +0000188 cmd, out, err, rc = self._run(exec_path, lit_config,
189 source_dir)
190 if rc != 0:
Daniel Dunbar3bc6a982013-02-12 19:28:51 +0000191 report = """Compiled With: %s\n""" % \
192 ' '.join(["'%s'" % a for a in compile_cmd])
193 report += """Command: %s\n""" % \
194 ' '.join(["'%s'" % a for a in cmd])
Dan Albert877409a2014-11-24 22:24:06 +0000195 report += """Exit Code: %d\n""" % rc
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000196 if out:
197 report += """Standard Output:\n--\n%s--""" % out
198 if err:
199 report += """Standard Error:\n--\n%s--""" % err
200 report += "\n\nCompiled test failed unexpectedly!"
201 return lit.Test.FAIL, report
202 finally:
203 try:
Dan Albert877409a2014-11-24 22:24:06 +0000204 # Note that cleanup of exec_file happens in `_clean()`. If
205 # you override this, cleanup is your reponsibility.
206 self._clean(exec_path)
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000207 except:
208 pass
209 return lit.Test.PASS, ""
210
Dan Albert2c262132014-08-21 17:30:44 +0000211
212class Configuration(object):
213 def __init__(self, lit_config, config):
214 self.lit_config = lit_config
215 self.config = config
216 self.cxx = None
217 self.src_root = None
218 self.obj_root = None
219 self.env = {}
220 self.compile_flags = []
Eric Fiselier9071bc02014-10-18 01:15:17 +0000221 self.library_paths = []
Dan Albert2c262132014-08-21 17:30:44 +0000222 self.link_flags = []
223 self.use_system_lib = False
Justin Bogner837cfe52014-09-03 04:32:08 +0000224 self.use_clang_verify = False
Dan Albert2c262132014-08-21 17:30:44 +0000225
226 if platform.system() not in ('Darwin', 'FreeBSD', 'Linux'):
227 self.lit_config.fatal("unrecognized system")
228
229 def get_lit_conf(self, name, default=None):
230 val = self.lit_config.params.get(name, None)
231 if val is None:
232 val = getattr(self.config, name, None)
233 if val is None:
234 val = default
235 return val
236
Justin Bogner837cfe52014-09-03 04:32:08 +0000237 def get_lit_bool(self, name):
238 conf = self.get_lit_conf(name)
239 if conf is None:
240 return None
241 if conf.lower() in ('1', 'true'):
242 return True
243 if conf.lower() in ('', '0', 'false'):
244 return False
245 self.lit_config.fatal(
246 "parameter '{}' should be true or false".format(name))
247
Dan Albert2c262132014-08-21 17:30:44 +0000248 def configure(self):
249 self.configure_cxx()
250 self.configure_triple()
251 self.configure_src_root()
252 self.configure_obj_root()
253 self.configure_use_system_lib()
Justin Bogner837cfe52014-09-03 04:32:08 +0000254 self.configure_use_clang_verify()
Dan Albert2c262132014-08-21 17:30:44 +0000255 self.configure_env()
256 self.configure_std_flag()
257 self.configure_compile_flags()
258 self.configure_link_flags()
259 self.configure_sanitizer()
260 self.configure_features()
261
262 def get_test_format(self):
263 return LibcxxTestFormat(
264 self.cxx,
Justin Bogner837cfe52014-09-03 04:32:08 +0000265 self.use_clang_verify,
Dan Albert2c262132014-08-21 17:30:44 +0000266 cpp_flags=['-nostdinc++'] + self.compile_flags,
267 ld_flags=['-nodefaultlibs'] + self.link_flags,
268 exec_env=self.env)
269
270 def configure_cxx(self):
271 # Gather various compiler parameters.
272 self.cxx = self.get_lit_conf('cxx_under_test')
273
274 # If no specific cxx_under_test was given, attempt to infer it as
275 # clang++.
276 if self.cxx is None:
277 clangxx = lit.util.which('clang++',
278 self.config.environment['PATH'])
279 if clangxx:
280 self.cxx = clangxx
281 self.lit_config.note(
282 "inferred cxx_under_test as: %r" % self.cxx)
283 if not self.cxx:
284 self.lit_config.fatal('must specify user parameter cxx_under_test '
285 '(e.g., --param=cxx_under_test=clang++)')
286
287 def configure_src_root(self):
288 self.src_root = self.get_lit_conf(
289 'libcxx_src_root', os.path.dirname(self.config.test_source_root))
290
291 def configure_obj_root(self):
292 self.obj_root = self.get_lit_conf('libcxx_obj_root', self.src_root)
293
294 def configure_use_system_lib(self):
295 # This test suite supports testing against either the system library or
296 # the locally built one; the former mode is useful for testing ABI
297 # compatibility between the current headers and a shipping dynamic
298 # library.
Justin Bogner837cfe52014-09-03 04:32:08 +0000299 self.use_system_lib = self.get_lit_bool('use_system_lib')
300 if self.use_system_lib is None:
Dan Albert2c262132014-08-21 17:30:44 +0000301 # Default to testing against the locally built libc++ library.
302 self.use_system_lib = False
303 self.lit_config.note(
304 "inferred use_system_lib as: %r" % self.use_system_lib)
305
Justin Bogner837cfe52014-09-03 04:32:08 +0000306 def configure_use_clang_verify(self):
307 '''If set, run clang with -verify on failing tests.'''
308 self.use_clang_verify = self.get_lit_bool('use_clang_verify')
309 if self.use_clang_verify is None:
310 # TODO: Default this to True when using clang.
311 self.use_clang_verify = False
312 self.lit_config.note(
313 "inferred use_clang_verify as: %r" % self.use_clang_verify)
314
Dan Albert2c262132014-08-21 17:30:44 +0000315 def configure_features(self):
Jonathan Roelofsd634a2c2014-09-05 19:03:46 +0000316 additional_features = self.get_lit_conf('additional_features')
317 if additional_features:
318 for f in additional_features.split(','):
319 self.config.available_features.add(f.strip())
Jonathan Roelofs217bdc12014-09-05 17:21:57 +0000320
Dan Albert2c262132014-08-21 17:30:44 +0000321 # Figure out which of the required locales we support
322 locales = {
323 'Darwin': {
324 'en_US.UTF-8': 'en_US.UTF-8',
325 'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
326 'fr_FR.UTF-8': 'fr_FR.UTF-8',
327 'fr_CA.ISO8859-1': 'cs_CZ.ISO8859-1',
328 'ru_RU.UTF-8': 'ru_RU.UTF-8',
329 'zh_CN.UTF-8': 'zh_CN.UTF-8',
330 },
331 'FreeBSD': {
332 'en_US.UTF-8': 'en_US.UTF-8',
333 'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
334 'fr_FR.UTF-8': 'fr_FR.UTF-8',
335 'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
336 'ru_RU.UTF-8': 'ru_RU.UTF-8',
337 'zh_CN.UTF-8': 'zh_CN.UTF-8',
338 },
339 'Linux': {
340 'en_US.UTF-8': 'en_US.UTF-8',
341 'cs_CZ.ISO8859-2': 'cs_CZ.ISO-8859-2',
342 'fr_FR.UTF-8': 'fr_FR.UTF-8',
343 'fr_CA.ISO8859-1': 'fr_CA.ISO-8859-1',
344 'ru_RU.UTF-8': 'ru_RU.UTF-8',
345 'zh_CN.UTF-8': 'zh_CN.UTF-8',
346 },
347 'Windows': {
348 'en_US.UTF-8': 'English_United States.1252',
349 'cs_CZ.ISO8859-2': 'Czech_Czech Republic.1250',
350 'fr_FR.UTF-8': 'French_France.1252',
351 'fr_CA.ISO8859-1': 'French_Canada.1252',
352 'ru_RU.UTF-8': 'Russian_Russia.1251',
353 'zh_CN.UTF-8': 'Chinese_China.936',
354 },
355 }
356
357 default_locale = locale.setlocale(locale.LC_ALL)
358 for feature, loc in locales[platform.system()].items():
359 try:
360 locale.setlocale(locale.LC_ALL, loc)
Eric Fiselierae6e58c2014-08-23 04:02:21 +0000361 self.config.available_features.add('locale.{0}'.format(feature))
Dan Albert2c262132014-08-21 17:30:44 +0000362 except:
Eric Fiselierae6e58c2014-08-23 04:02:21 +0000363 self.lit_config.warning('The locale {0} is not supported by '
Dan Albert2c262132014-08-21 17:30:44 +0000364 'your platform. Some tests will be '
365 'unsupported.'.format(loc))
366 locale.setlocale(locale.LC_ALL, default_locale)
367
368 # Write an "available feature" that combines the triple when
369 # use_system_lib is enabled. This is so that we can easily write XFAIL
370 # markers for tests that are known to fail with versions of libc++ as
371 # were shipped with a particular triple.
372 if self.use_system_lib:
Dan Albert2c262132014-08-21 17:30:44 +0000373 self.config.available_features.add(
Eric Fiselier2b0f03a2014-10-27 22:14:25 +0000374 'with_system_lib=%s' % self.config.target_triple)
Dan Albert2c262132014-08-21 17:30:44 +0000375
Jonathan Roelofs217bdc12014-09-05 17:21:57 +0000376 if 'libcpp-has-no-threads' in self.config.available_features:
377 self.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
378
379 if 'libcpp-has-no-monotonic-clock' in self.config.available_features:
380 self.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
381
Eric Fiselieraeff14f2014-11-21 08:02:38 +0000382 # Some linux distributions have different locale data than others.
383 # Insert the distributions name and name-version into the available
384 # features to allow tests to XFAIL on them.
385 if sys.platform.startswith('linux'):
Eric Fiselier1567ac82014-11-21 08:54:35 +0000386 name, ver, _ = platform.linux_distribution()
387 name = name.lower().strip()
388 ver = ver.lower().strip()
389 self.config.available_features.add(name)
390 self.config.available_features.add('%s-%s' % (name, ver))
Eric Fiselieraeff14f2014-11-21 08:02:38 +0000391
Dan Albert2c262132014-08-21 17:30:44 +0000392 def configure_compile_flags(self):
393 # Configure extra compiler flags.
394 self.compile_flags += ['-I' + self.src_root + '/include',
395 '-I' + self.src_root + '/test/support']
Eric Fiselier5636e632014-10-23 22:57:56 +0000396 if sys.platform.startswith('linux'):
Eric Fiselier9071bc02014-10-18 01:15:17 +0000397 self.compile_flags += ['-D__STDC_FORMAT_MACROS',
398 '-D__STDC_LIMIT_MACROS',
399 '-D__STDC_CONSTANT_MACROS']
Dan Albert2c262132014-08-21 17:30:44 +0000400
401 def configure_link_flags(self):
Eric Fiselier9071bc02014-10-18 01:15:17 +0000402 # Configure library search paths
Eric Fiseliercb7e32c2014-10-19 00:42:41 +0000403 abi_library_path = self.get_lit_conf('abi_library_path', '')
Eric Fiselier9071bc02014-10-18 01:15:17 +0000404 self.link_flags += ['-L' + self.obj_root + '/lib']
Eric Fiseliercb7e32c2014-10-19 00:42:41 +0000405 if not self.use_system_lib:
406 self.link_flags += ['-Wl,-rpath', '-Wl,' + self.obj_root + '/lib']
407 if abi_library_path:
408 self.link_flags += ['-L' + abi_library_path,
409 '-Wl,-rpath', '-Wl,' + abi_library_path]
Eric Fiselier9071bc02014-10-18 01:15:17 +0000410 # Configure libraries
411 self.link_flags += ['-lc++']
Dan Albert2c262132014-08-21 17:30:44 +0000412 link_flags_str = self.get_lit_conf('link_flags')
413 if link_flags_str is None:
414 cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
415 if cxx_abi == 'libstdc++':
416 self.link_flags += ['-lstdc++']
417 elif cxx_abi == 'libsupc++':
418 self.link_flags += ['-lsupc++']
419 elif cxx_abi == 'libcxxabi':
420 self.link_flags += ['-lc++abi']
421 elif cxx_abi == 'libcxxrt':
422 self.link_flags += ['-lcxxrt']
423 elif cxx_abi == 'none':
424 pass
425 else:
426 self.lit_config.fatal(
427 'C++ ABI setting %s unsupported for tests' % cxx_abi)
428
429 if sys.platform == 'darwin':
430 self.link_flags += ['-lSystem']
Eric Fiselier5636e632014-10-23 22:57:56 +0000431 elif sys.platform.startswith('linux'):
Dan Albert2c262132014-08-21 17:30:44 +0000432 self.link_flags += ['-lgcc_eh', '-lc', '-lm', '-lpthread',
433 '-lrt', '-lgcc_s']
434 elif sys.platform.startswith('freebsd'):
435 self.link_flags += ['-lc', '-lm', '-pthread', '-lgcc_s']
436 else:
Eric Fiselier9071bc02014-10-18 01:15:17 +0000437 self.lit_config.fatal("unrecognized system: %r" % sys.platform)
Dan Albert2c262132014-08-21 17:30:44 +0000438
439 self.lit_config.note(
440 "inferred link_flags as: %r" % self.link_flags)
441 if link_flags_str:
442 self.link_flags += shlex.split(link_flags_str)
443
Dan Albert2c262132014-08-21 17:30:44 +0000444
445 def configure_std_flag(self):
446 # Try and get the std version from the command line. Fall back to
447 # default given in lit.site.cfg is not present. If default is not
448 # present then force c++11.
449 std = self.get_lit_conf('std')
450 if std is None:
451 std = 'c++11'
452 self.lit_config.note('using default std: \'-std=c++11\'')
Eric Fiselierae6e58c2014-08-23 04:02:21 +0000453 self.compile_flags += ['-std={0}'.format(std)]
Dan Albert2c262132014-08-21 17:30:44 +0000454 self.config.available_features.add(std)
455
456 def configure_sanitizer(self):
457 san = self.get_lit_conf('llvm_use_sanitizer', '').strip()
458 if san:
Eric Fiselier44678f42014-11-14 02:47:08 +0000459 # Search for llvm-symbolizer along the compiler path first
460 # and then along the PATH env variable.
461 symbolizer_search_paths = os.environ.get('PATH', '')
462 cxx_path = lit.util.which(self.cxx)
463 if cxx_path is not None:
464 symbolizer_search_paths = os.path.dirname(cxx_path) + \
465 os.pathsep + symbolizer_search_paths
466 llvm_symbolizer = lit.util.which('llvm-symbolizer',
467 symbolizer_search_paths)
468 # Setup the sanitizer compile flags
Eric Fiselier1383dc52014-11-14 22:18:03 +0000469 self.compile_flags += ['-g', '-fno-omit-frame-pointer']
Eric Fiselier5636e632014-10-23 22:57:56 +0000470 if sys.platform.startswith('linux'):
Eric Fiselier3de9baa2014-10-23 02:54:15 +0000471 self.link_flags += ['-ldl']
Dan Albert2c262132014-08-21 17:30:44 +0000472 if san == 'Address':
473 self.compile_flags += ['-fsanitize=address']
Eric Fiselier44678f42014-11-14 02:47:08 +0000474 if llvm_symbolizer is not None:
475 self.env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
Dan Albert2c262132014-08-21 17:30:44 +0000476 self.config.available_features.add('asan')
477 elif san == 'Memory' or san == 'MemoryWithOrigins':
478 self.compile_flags += ['-fsanitize=memory']
479 if san == 'MemoryWithOrigins':
480 self.compile_flags += ['-fsanitize-memory-track-origins']
Eric Fiselier44678f42014-11-14 02:47:08 +0000481 if llvm_symbolizer is not None:
482 self.env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
Dan Albert2c262132014-08-21 17:30:44 +0000483 self.config.available_features.add('msan')
Eric Fiselier66d529f2014-10-16 23:21:59 +0000484 elif san == 'Undefined':
485 self.compile_flags += ['-fsanitize=undefined',
486 '-fno-sanitize=vptr,function',
Eric Fiselier05123a82014-11-14 02:07:52 +0000487 '-fno-sanitize-recover', '-O3']
Eric Fiselier66d529f2014-10-16 23:21:59 +0000488 self.config.available_features.add('ubsan')
Eric Fiselieraf2976d2014-11-18 21:26:45 +0000489 elif san == 'Thread':
490 self.compile_flags += ['-fsanitize=thread']
491 self.config.available_features.add('tsan')
Dan Albert2c262132014-08-21 17:30:44 +0000492 else:
493 self.lit_config.fatal('unsupported value for '
Eric Fiselierae6e58c2014-08-23 04:02:21 +0000494 'libcxx_use_san: {0}'.format(san))
Dan Albert2c262132014-08-21 17:30:44 +0000495
496 def configure_triple(self):
497 # Get or infer the target triple.
498 self.config.target_triple = self.get_lit_conf('target_triple')
499 # If no target triple was given, try to infer it from the compiler
500 # under test.
501 if not self.config.target_triple:
Eric Fiselier2b0f03a2014-10-27 22:14:25 +0000502 target_triple = lit.util.capture(
Dan Albert2c262132014-08-21 17:30:44 +0000503 [self.cxx, '-dumpmachine']).strip()
Eric Fiselier2b0f03a2014-10-27 22:14:25 +0000504 # Drop sub-major version components from the triple, because the
505 # current XFAIL handling expects exact matches for feature checks.
Eric Fiseliera01a6232014-10-28 18:03:38 +0000506 # Example: x86_64-apple-darwin14.0.0 -> x86_64-apple-darwin14
Eric Fiselier2b0f03a2014-10-27 22:14:25 +0000507 # The 5th group handles triples greater than 3 parts
508 # (ex x86_64-pc-linux-gnu).
509 target_triple = re.sub(r'([^-]+)-([^-]+)-([^.]+)([^-]*)(.*)',
510 r'\1-\2-\3\5', target_triple)
511 # linux-gnu is needed in the triple to properly identify linuxes
512 # that use GLIBC. Handle redhat and opensuse triples as special
513 # cases and append the missing `-gnu` portion.
514 if target_triple.endswith('redhat-linux') or \
515 target_triple.endswith('suse-linux'):
516 target_triple += '-gnu'
517 self.config.target_triple = target_triple
Dan Albert2c262132014-08-21 17:30:44 +0000518 self.lit_config.note(
519 "inferred target_triple as: %r" % self.config.target_triple)
520
521 def configure_env(self):
522 # Configure extra linker parameters.
523 if sys.platform == 'darwin':
524 if not self.use_system_lib:
525 self.env['DYLD_LIBRARY_PATH'] = os.path.join(self.obj_root,
526 'lib')
527
528
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000529# name: The name of this test suite.
530config.name = 'libc++'
531
532# suffixes: A list of file extensions to treat as test files.
533config.suffixes = ['.cpp']
534
535# test_source_root: The root path where tests are located.
536config.test_source_root = os.path.dirname(__file__)
537
Dan Albert877409a2014-11-24 22:24:06 +0000538cfg_variant = getattr(config, 'configuration_variant', '')
539if cfg_variant:
540 print 'Using configuration variant: %s' % cfg_variant
541
542# Construct an object of the type named `<VARIANT>Configuration`.
543configuration = globals()['%sConfiguration' % cfg_variant](lit_config, config)
Dan Albert2c262132014-08-21 17:30:44 +0000544configuration.configure()
545config.test_format = configuration.get_test_format()