aboutsummaryrefslogtreecommitdiff
path: root/test/libcxx
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-09-06 18:46:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-09-06 18:46:46 +0000
commit61b9a7258a7693d7f3674a5a1daf7b036ff1d382 (patch)
treeec41ed70ffca97240e76f9a78bb2dedba28f310c /test/libcxx
parentf857581820d15e410e9945d2fcd5f7163be25a96 (diff)
downloadsrc-61b9a7258a7693d7f3674a5a1daf7b036ff1d382.tar.gz
src-61b9a7258a7693d7f3674a5a1daf7b036ff1d382.zip
Import libc++ 3.7.0 release (r246257).vendor/libc++/libc++-release_370-r246257
Notes
Notes: svn path=/vendor/libc++/dist/; revision=287518 svn path=/vendor/libc++/libc++-release_370-r246257/; revision=287519; tag=vendor/libc++/libc++-release_370-r246257
Diffstat (limited to 'test/libcxx')
-rw-r--r--test/libcxx/__init__.py0
-rw-r--r--test/libcxx/compiler.py152
-rw-r--r--test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp48
-rw-r--r--test/libcxx/double_include.sh.cpp114
-rw-r--r--test/libcxx/experimental/algorithms/header.algorithm.synop/includes.pass.cpp20
-rw-r--r--test/libcxx/experimental/algorithms/version.pass.cpp20
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp86
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp95
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp67
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp48
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp94
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp108
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp57
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp68
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp71
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp31
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp50
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp12
-rw-r--r--test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp24
-rw-r--r--test/libcxx/experimental/utilities/ratio/version.pass.cpp20
-rw-r--r--test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp22
-rw-r--r--test/libcxx/experimental/utilities/syserror/version.pass.cpp20
-rw-r--r--test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp22
-rw-r--r--test/libcxx/experimental/utilities/time/version.pass.cpp20
-rw-r--r--test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp21
-rw-r--r--test/libcxx/experimental/utilities/tuple/version.pass.cpp20
-rw-r--r--test/libcxx/selftest/not_test.sh.cpp17
-rw-r--r--test/libcxx/selftest/test.fail.cpp11
-rw-r--r--test/libcxx/selftest/test.pass.cpp13
-rw-r--r--test/libcxx/selftest/test.sh.cpp16
-rw-r--r--test/libcxx/selftest/test_macros.pass.cpp58
-rw-r--r--test/libcxx/test/__init__.py0
-rw-r--r--test/libcxx/test/config.py709
-rw-r--r--test/libcxx/test/executor.py191
-rw-r--r--test/libcxx/test/format.py163
-rw-r--r--test/libcxx/test/target_info.py55
-rw-r--r--test/libcxx/test/tracing.py34
-rw-r--r--test/libcxx/type_traits/convert_to_integral.pass.cpp94
-rw-r--r--test/libcxx/util.py46
-rw-r--r--test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp94
40 files changed, 2811 insertions, 0 deletions
diff --git a/test/libcxx/__init__.py b/test/libcxx/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/libcxx/__init__.py
diff --git a/test/libcxx/compiler.py b/test/libcxx/compiler.py
new file mode 100644
index 000000000000..7afbed461e31
--- /dev/null
+++ b/test/libcxx/compiler.py
@@ -0,0 +1,152 @@
+import os
+import lit.util
+import libcxx.util
+
+
+class CXXCompiler(object):
+ def __init__(self, path, flags=None, compile_flags=None, link_flags=None,
+ use_ccache=False):
+ self.path = path
+ self.flags = list(flags or [])
+ self.compile_flags = list(compile_flags or [])
+ self.link_flags = list(link_flags or [])
+ self.use_ccache = use_ccache
+ self.type = None
+ self.version = None
+ self._initTypeAndVersion()
+
+ def _initTypeAndVersion(self):
+ # Get compiler type and version
+ macros = self.dumpMacros()
+ if macros is None:
+ return
+ compiler_type = None
+ major_ver = minor_ver = patchlevel = None
+ if '__clang__' in macros.keys():
+ compiler_type = 'clang'
+ # Treat apple's llvm fork differently.
+ if '__apple_build_version__' in macros.keys():
+ compiler_type = 'apple-clang'
+ major_ver = macros['__clang_major__']
+ minor_ver = macros['__clang_minor__']
+ patchlevel = macros['__clang_patchlevel__']
+ elif '__GNUC__' in macros.keys():
+ compiler_type = 'gcc'
+ major_ver = macros['__GNUC__']
+ minor_ver = macros['__GNUC_MINOR__']
+ patchlevel = macros['__GNUC_PATCHLEVEL__']
+ self.type = compiler_type
+ self.version = (major_ver, minor_ver, patchlevel)
+
+ def _basicCmd(self, source_files, out, is_link=False, input_is_cxx=False):
+ cmd = []
+ if self.use_ccache and not is_link:
+ cmd += ['ccache']
+ cmd += [self.path]
+ if out is not None:
+ cmd += ['-o', out]
+ if input_is_cxx:
+ cmd += ['-x', 'c++']
+ if isinstance(source_files, list):
+ cmd += source_files
+ elif isinstance(source_files, str):
+ cmd += [source_files]
+ else:
+ raise TypeError('source_files must be a string or list')
+ return cmd
+
+ def preprocessCmd(self, source_files, out=None, flags=[]):
+ cmd = self._basicCmd(source_files, out, input_is_cxx=True) + ['-E']
+ cmd += self.flags + self.compile_flags + flags
+ return cmd
+
+ def compileCmd(self, source_files, out=None, flags=[]):
+ cmd = self._basicCmd(source_files, out, input_is_cxx=True) + ['-c']
+ cmd += self.flags + self.compile_flags + flags
+ return cmd
+
+ def linkCmd(self, source_files, out=None, flags=[]):
+ cmd = self._basicCmd(source_files, out, is_link=True)
+ cmd += self.flags + self.link_flags + flags
+ return cmd
+
+ def compileLinkCmd(self, source_files, out=None, flags=[]):
+ cmd = self._basicCmd(source_files, out, is_link=True)
+ cmd += self.flags + self.compile_flags + self.link_flags + flags
+ return cmd
+
+ def preprocess(self, source_files, out=None, flags=[], env=None, cwd=None):
+ cmd = self.preprocessCmd(source_files, out, flags)
+ out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
+ return cmd, out, err, rc
+
+ def compile(self, source_files, out=None, flags=[], env=None, cwd=None):
+ cmd = self.compileCmd(source_files, out, flags)
+ out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
+ return cmd, out, err, rc
+
+ def link(self, source_files, out=None, flags=[], env=None, cwd=None):
+ cmd = self.linkCmd(source_files, out, flags)
+ out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
+ return cmd, out, err, rc
+
+ def compileLink(self, source_files, out=None, flags=[], env=None,
+ cwd=None):
+ cmd = self.compileLinkCmd(source_files, out, flags)
+ out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
+ return cmd, out, err, rc
+
+ def compileLinkTwoSteps(self, source_file, out=None, object_file=None,
+ flags=[], env=None, cwd=None):
+ if not isinstance(source_file, str):
+ raise TypeError('This function only accepts a single input file')
+ if object_file is None:
+ # Create, use and delete a temporary object file if none is given.
+ with_fn = lambda: libcxx.util.guardedTempFilename(suffix='.o')
+ else:
+ # Otherwise wrap the filename in a context manager function.
+ with_fn = lambda: libcxx.util.nullContext(object_file)
+ with with_fn() as object_file:
+ cc_cmd, cc_stdout, cc_stderr, rc = self.compile(
+ source_file, object_file, flags=flags, env=env, cwd=cwd)
+ if rc != 0:
+ return cc_cmd, cc_stdout, cc_stderr, rc
+
+ link_cmd, link_stdout, link_stderr, rc = self.link(
+ object_file, out=out, flags=flags, env=env, cwd=cwd)
+ return (cc_cmd + ['&&'] + link_cmd, cc_stdout + link_stdout,
+ cc_stderr + link_stderr, rc)
+
+ def dumpMacros(self, source_files=None, flags=[], env=None, cwd=None):
+ if source_files is None:
+ source_files = os.devnull
+ flags = ['-dM'] + flags
+ cmd, out, err, rc = self.preprocess(source_files, flags=flags, env=env,
+ cwd=cwd)
+ if rc != 0:
+ return None
+ parsed_macros = {}
+ lines = [l.strip() for l in out.split('\n') if l.strip()]
+ for l in lines:
+ assert l.startswith('#define ')
+ l = l[len('#define '):]
+ macro, _, value = l.partition(' ')
+ parsed_macros[macro] = value
+ return parsed_macros
+
+ def getTriple(self):
+ cmd = [self.path] + self.flags + ['-dumpmachine']
+ return lit.util.capture(cmd).strip()
+
+ def hasCompileFlag(self, flag):
+ if isinstance(flag, list):
+ flags = list(flag)
+ else:
+ flags = [flag]
+ # Add -Werror to ensure that an unrecognized flag causes a non-zero
+ # exit code. -Werror is supported on all known compiler types.
+ if self.type is not None:
+ flags += ['-Werror']
+ cmd, out, err, rc = self.compile(os.devnull, out=os.devnull,
+ flags=flags)
+ return rc == 0
diff --git a/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp b/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp
new file mode 100644
index 000000000000..76ceafed2208
--- /dev/null
+++ b/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Check that we don't allocate when trying to insert a duplicate value into a
+// unordered_set. See PR12999 http://llvm.org/bugs/show_bug.cgi?id=12999
+
+#include <cassert>
+#include <unordered_set>
+#include "count_new.hpp"
+#include "MoveOnly.h"
+
+int main()
+{
+ {
+ std::unordered_set<int> s;
+ assert(globalMemCounter.checkNewCalledEq(0));
+
+ for(int i=0; i < 100; ++i)
+ s.insert(3);
+
+ assert(s.size() == 1);
+ assert(s.count(3) == 1);
+ assert(globalMemCounter.checkNewCalledEq(2));
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ globalMemCounter.reset();
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ std::unordered_set<MoveOnly> s;
+ assert(globalMemCounter.checkNewCalledEq(0));
+
+ for(int i=0; i<100; i++)
+ s.insert(MoveOnly(3));
+
+ assert(s.size() == 1);
+ assert(s.count(MoveOnly(3)) == 1);
+ assert(globalMemCounter.checkNewCalledEq(2));
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ globalMemCounter.reset();
+#endif
+}
diff --git a/test/libcxx/double_include.sh.cpp b/test/libcxx/double_include.sh.cpp
new file mode 100644
index 000000000000..5620e5b35c2b
--- /dev/null
+++ b/test/libcxx/double_include.sh.cpp
@@ -0,0 +1,114 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test that we can include each header in two TU's and link them together.
+
+// RUN: %cxx -c %s -o %t.first.o %flags %compile_flags
+// RUN: %cxx -c %s -o %t.second.o -DWITH_MAIN %flags %compile_flags
+// RUN: %cxx -o %t.exe %t.first.o %t.second.o %flags %link_flags
+// RUN: %run
+
+#include <algorithm>
+#include <array>
+#include <bitset>
+#include <cassert>
+#include <ccomplex>
+#include <cctype>
+#include <cerrno>
+#include <cfenv>
+#include <cfloat>
+#include <chrono>
+#include <cinttypes>
+#include <ciso646>
+#include <climits>
+#include <clocale>
+#include <cmath>
+#include <codecvt>
+#include <complex>
+#include <complex.h>
+#include <condition_variable>
+#include <csetjmp>
+#include <csignal>
+#include <cstdarg>
+#include <cstdbool>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctgmath>
+#include <ctime>
+#include <cwchar>
+#include <cwctype>
+#include <deque>
+#include <exception>
+#include <experimental/algorithm>
+#include <experimental/chrono>
+#include <experimental/dynarray>
+#include <experimental/optional>
+#include <experimental/string_view>
+#include <experimental/system_error>
+#include <experimental/type_traits>
+#include <experimental/utility>
+#include <ext/hash_map>
+#include <ext/hash_set>
+#include <forward_list>
+#include <fstream>
+#include <functional>
+#include <initializer_list>
+#include <iomanip>
+#include <ios>
+#include <iosfwd>
+#include <iostream>
+#include <istream>
+#include <iterator>
+#include <limits>
+#include <list>
+#include <locale>
+#include <map>
+#include <memory>
+#include <new>
+#include <numeric>
+#include <ostream>
+#include <queue>
+#include <random>
+#include <ratio>
+#include <regex>
+#include <scoped_allocator>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <stdexcept>
+#include <streambuf>
+#include <string>
+#include <strstream>
+#include <system_error>
+#include <tgmath.h>
+#include <tuple>
+#include <typeindex>
+#include <typeinfo>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <valarray>
+#include <vector>
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+#include <atomic>
+#include <future>
+#include <mutex>
+#include <shared_mutex>
+#include <thread>
+#endif
+
+#if defined(WITH_MAIN)
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/algorithms/header.algorithm.synop/includes.pass.cpp b/test/libcxx/experimental/algorithms/header.algorithm.synop/includes.pass.cpp
new file mode 100644
index 000000000000..accdd699c4f9
--- /dev/null
+++ b/test/libcxx/experimental/algorithms/header.algorithm.synop/includes.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/algorithm>
+
+#include <experimental/algorithm>
+
+#ifndef _LIBCPP_ALGORITHM
+# error "<experimental/algorithm> must include <algorithm>"
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/algorithms/version.pass.cpp b/test/libcxx/experimental/algorithms/version.pass.cpp
new file mode 100644
index 000000000000..6d9d0c6b2f38
--- /dev/null
+++ b/test/libcxx/experimental/algorithms/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/algorithm>
+
+#include <experimental/algorithm>
+
+#ifndef _LIBCPP_VERSION
+# error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
new file mode 100644
index 000000000000..d274bc030881
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.cons
+
+// template <class Alloc>
+// dynarray(size_type c, const Alloc& alloc);
+// template <class Alloc>
+// dynarray(size_type c, const T& v, const Alloc& alloc);
+// template <class Alloc>
+// dynarray(const dynarray& d, const Alloc& alloc);
+// template <class Alloc>
+// dynarray(initializer_list<T>, const Alloc& alloc);
+
+// ~dynarray();
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+#include "test_allocator.h"
+
+using std::experimental::dynarray;
+
+template <class T, class Allocator>
+void check_allocator ( const dynarray<T> &dyn, const Allocator &alloc ) {
+ for ( int i = 0; i < dyn.size (); ++i )
+ assert ( dyn[i].get_allocator() == alloc );
+}
+
+template <class T, class Allocator>
+void test ( const std::initializer_list<T> &vals, const Allocator &alloc ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( vals, alloc );
+ assert ( d1.size () == vals.size() );
+ assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ()));
+ check_allocator ( d1, alloc );
+ }
+
+
+template <class T, class Allocator>
+void test ( const T &val, const Allocator &alloc1, const Allocator &alloc2 ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( 4, alloc1 );
+ assert ( d1.size () == 4 );
+ assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
+ check_allocator ( d1, alloc1 );
+
+ dynA d2 ( 7, val, alloc1 );
+ assert ( d2.size () == 7 );
+ assert ( std::all_of ( d2.begin (), d2.end (), [&val]( const T &item ){ return item == val; } ));
+ check_allocator ( d2, alloc1 );
+
+ dynA d3 ( d2, alloc2 );
+ assert ( d3.size () == 7 );
+ assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } ));
+ check_allocator ( d3, alloc2 );
+ }
+
+int main()
+{
+// This test is waiting on the resolution of LWG issue #2235
+// typedef test_allocator<char> Alloc;
+// typedef std::basic_string<char, std::char_traits<char>, Alloc> nstr;
+//
+// test ( nstr("fourteen"), Alloc(3), Alloc(4) );
+// test ( { nstr("1"), nstr("1"), nstr("2"), nstr("3"), nstr("5"), nstr("8")}, Alloc(6));
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
new file mode 100644
index 000000000000..0effac2fc142
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.cons
+
+// explicit dynarray(size_type c);
+// dynarray(size_type c, const T& v);
+// dynarray(initializer_list<T>);
+// dynarray(const dynarray& d);
+
+// ~dynarray();
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void test ( const std::initializer_list<T> &vals ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( vals );
+ assert ( d1.size () == vals.size() );
+ assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ()));
+ }
+
+
+template <class T>
+void test ( const T &val ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( 4 );
+ assert ( d1.size () == 4 );
+ assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
+
+ dynA d2 ( 7, val );
+ assert ( d2.size () == 7 );
+ assert ( std::all_of ( d2.begin (), d2.end (), [&val]( const T &item ){ return item == val; } ));
+
+ dynA d3 ( d2 );
+ assert ( d3.size () == 7 );
+ assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } ));
+ }
+
+void test_bad_length () {
+ try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) + 1 ); }
+ catch ( std::bad_array_length & ) { return ; }
+ assert ( false );
+ }
+
+void test_bad_alloc () {
+ try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) - 1 ); }
+ catch ( std::bad_alloc & ) { return ; }
+ assert ( false );
+ }
+
+int main()
+{
+// test<int> ( 14 ); // ints don't get default initialized
+ test<long> ( 0 );
+ test<double> ( 14.0 );
+ test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+ test<std::string> ( "fourteen" );
+
+ test ( { 1, 1, 2, 3, 5, 8 } );
+ test ( { 1., 1., 2., 3., 5., 8. } );
+ test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
+ std::string("5"), std::string("8")} );
+
+// Make sure we don't pick up the Allocator version here
+ dynarray<long> d1 ( 20, 3 );
+ assert ( d1.size() == 20 );
+ assert ( std::all_of ( d1.begin (), d1.end (), []( long item ){ return item == 3L; } ));
+
+ test_bad_length ();
+ test_bad_alloc ();
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
new file mode 100644
index 000000000000..b669f25948ed
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.data
+
+// T* data() noexcept;
+// const T* data() const noexcept;
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn ) {
+ const T *data = dyn.data ();
+ assert ( data != NULL );
+ assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+ }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn ) {
+ T *data = dyn.data ();
+ assert ( data != NULL );
+ assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+ }
+
+
+
+template <class T>
+void test ( const T &val ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( 4 );
+ dyn_test ( d1 );
+ dyn_test_const ( d1 );
+
+ dynA d2 ( 7, val );
+ dyn_test ( d2 );
+ dyn_test_const ( d2 );
+ }
+
+int main()
+{
+ test<int> ( 14 );
+ test<double> ( 14.0 );
+ test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+ test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
new file mode 100644
index 000000000000..c57887ddaf94
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.data
+
+// void fill(const T& v);
+// const T* data() const noexcept;
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void test ( const T &val ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( 4 );
+ d1.fill ( val );
+ assert ( std::all_of ( d1.begin (), d1.end (),
+ [&val]( const T &item ){ return item == val; } ));
+ }
+
+int main()
+{
+ test<int> ( 14 );
+ test<double> ( 14.0 );
+ test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+ test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
new file mode 100644
index 000000000000..4d77cf732758
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// const_reference at(size_type n) const;
+// reference at(size_type n);
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_at_fail ( dynarray<T> &dyn, size_t sz ) {
+ try { dyn.at (sz); }
+ catch (const std::out_of_range &) { return; }
+ assert ( false );
+ }
+
+template <class T>
+void dyn_at_fail_const ( const dynarray<T> &dyn, size_t sz ) {
+ try { dyn.at (sz); }
+ catch (const std::out_of_range &) { return; }
+ assert ( false );
+ }
+
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+ const T *data = dyn.data ();
+ auto it = vals.begin ();
+ for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+ assert ( data + i == &dyn.at(i));
+ assert ( *it == dyn.at(i));
+ }
+
+ dyn_at_fail_const ( dyn, dyn.size ());
+ dyn_at_fail_const ( dyn, 2*dyn.size ());
+ dyn_at_fail_const ( dyn, size_t (-1));
+ }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+ T *data = dyn.data ();
+ auto it = vals.begin ();
+ for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+ assert ( data + i == &dyn.at(i));
+ assert ( *it == dyn.at(i));
+ }
+
+ dyn_at_fail ( dyn, dyn.size ());
+ dyn_at_fail ( dyn, 2*dyn.size ());
+ dyn_at_fail ( dyn, size_t (-1));
+ }
+
+
+template <class T>
+void test ( std::initializer_list<T> vals ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( vals );
+ dyn_test ( d1, vals );
+ dyn_test_const ( d1, vals );
+ }
+
+int main()
+{
+ test ( { 1, 1, 2, 3, 5, 8 } );
+ test ( { 1., 1., 2., 3., 5., 8. } );
+ test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
+ std::string("5"), std::string("8")} );
+
+ test<int> ( {} );
+ test<std::complex<double>> ( {} );
+ test<std::string> ( {} );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
new file mode 100644
index 000000000000..695e1aa9f14a
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+
+// iterator begin() noexcept;
+// const_iterator begin() const noexcept;
+// const_iterator cbegin() const noexcept;
+// iterator end() noexcept;
+// const_iterator end() const noexcept;
+// const_iterator cend() const noexcept;
+//
+// reverse_iterator rbegin() noexcept;
+// const_reverse_iterator rbegin() const noexcept;
+// const_reverse_iterator crbegin() const noexcept;
+// reverse_iterator rend() noexcept;
+// const_reverse_iterator rend() const noexcept;
+// const_reverse_iterator crend() const noexcept;
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn ) {
+ const T *data = dyn.data ();
+ assert ( data == &*dyn.begin ());
+ assert ( data == &*dyn.cbegin ());
+
+ assert ( data + dyn.size() - 1 == &*dyn.rbegin ());
+ assert ( data + dyn.size() - 1 == &*dyn.crbegin ());
+
+ assert ( dyn.size () == std::distance ( dyn.begin(), dyn.end()));
+ assert ( dyn.size () == std::distance ( dyn.cbegin(), dyn.cend()));
+ assert ( dyn.size () == std::distance ( dyn.rbegin(), dyn.rend()));
+ assert ( dyn.size () == std::distance ( dyn.crbegin(), dyn.crend()));
+
+ assert ( dyn.begin () == dyn.cbegin ());
+ assert ( &*dyn.begin () == &*dyn.cbegin ());
+ assert ( dyn.rbegin () == dyn.crbegin ());
+ assert ( &*dyn.rbegin () == &*dyn.crbegin ());
+ assert ( dyn.end () == dyn.cend ());
+ assert ( dyn.rend () == dyn.crend ());
+ }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn ) {
+ T *data = dyn.data ();
+ assert ( data == &*dyn.begin ());
+ assert ( data == &*dyn.cbegin ());
+
+ assert ( data + dyn.size() - 1 == &*dyn.rbegin ());
+ assert ( data + dyn.size() - 1 == &*dyn.crbegin ());
+
+ assert ( dyn.size () == std::distance ( dyn.begin(), dyn.end()));
+ assert ( dyn.size () == std::distance ( dyn.cbegin(), dyn.cend()));
+ assert ( dyn.size () == std::distance ( dyn.rbegin(), dyn.rend()));
+ assert ( dyn.size () == std::distance ( dyn.crbegin(), dyn.crend()));
+
+ assert ( dyn.begin () == dyn.cbegin ());
+ assert ( &*dyn.begin () == &*dyn.cbegin ());
+ assert ( dyn.rbegin () == dyn.crbegin ());
+ assert ( &*dyn.rbegin () == &*dyn.crbegin ());
+ assert ( dyn.end () == dyn.cend ());
+ assert ( dyn.rend () == dyn.crend ());
+ }
+
+
+template <class T>
+void test ( const T &val ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( 4 );
+ dyn_test ( d1 );
+ dyn_test_const ( d1 );
+
+ dynA d2 ( 7, val );
+ dyn_test ( d2 );
+ dyn_test_const ( d2 );
+ }
+
+int main()
+{
+ test<int> ( 14 );
+ test<double> ( 14.0 );
+ test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+ test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
new file mode 100644
index 000000000000..6d28eef1b057
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// size_type size() const noexcept;
+// size_type max_size() const noexcept;
+// bool empty() const noexcept;
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test ( const dynarray<T> &dyn, size_t sz ) {
+ assert ( dyn.size () == sz );
+ assert ( dyn.max_size () == sz );
+ assert ( dyn.empty () == ( sz == 0 ));
+ }
+
+template <class T>
+void test ( std::initializer_list<T> vals ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( vals );
+ dyn_test ( d1, vals.size ());
+ }
+
+int main()
+{
+ test ( { 1, 1, 2, 3, 5, 8 } );
+ test ( { 1., 1., 2., 3., 5., 8. } );
+ test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
+ std::string("5"), std::string("8")} );
+
+ test<int> ( {} );
+ test<std::complex<double>> ( {} );
+ test<std::string> ( {} );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
new file mode 100644
index 000000000000..e82aa64b98b6
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// reference front();
+// const_reference front() const;
+// reference back();
+// const_reference back() const;
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn ) {
+ const T *data = dyn.data ();
+ assert ( *data == dyn.front ());
+ assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+ }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn ) {
+ T *data = dyn.data ();
+ assert ( *data == dyn.front ());
+ assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+ }
+
+
+template <class T>
+void test ( const T &val ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( 4 );
+ dyn_test ( d1 );
+ dyn_test_const ( d1 );
+
+ dynA d2 ( 7, val );
+ dyn_test ( d2 );
+ dyn_test_const ( d2 );
+ }
+
+int main()
+{
+ test<int> ( 14 );
+ test<double> ( 14.0 );
+ test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+ test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
new file mode 100644
index 000000000000..7317a2023cb1
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// const_reference at(size_type n) const;
+// reference at(size_type n);
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+ const T *data = dyn.data ();
+ auto it = vals.begin ();
+ for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+ assert ( data + i == &dyn[i]);
+ assert ( *it == dyn[i]);
+ }
+ }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+ T *data = dyn.data ();
+ auto it = vals.begin ();
+ for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+ assert ( data + i == &dyn[i]);
+ assert ( *it == dyn[i]);
+ }
+ }
+
+
+template <class T>
+void test ( std::initializer_list<T> vals ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( vals );
+ dyn_test ( d1, vals );
+ dyn_test_const ( d1, vals );
+ }
+
+int main()
+{
+ test ( { 1, 1, 2, 3, 5, 8 } );
+ test ( { 1., 1., 2., 3., 5., 8. } );
+ test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"),
+ std::string("5"), std::string("8")} );
+
+ test<int> ( {} );
+ test<std::complex<double>> ( {} );
+ test<std::string> ( {} );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
new file mode 100644
index 000000000000..9b8240d4cd82
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.data
+
+// template <class Type, class Alloc>
+// struct uses_allocator<dynarray<Type>, Alloc> : true_type { };
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include "test_allocator.h"
+
+using std::experimental::dynarray;
+
+int main()
+{
+ static_assert ( std::uses_allocator<dynarray<int>, test_allocator<int>>::value, "" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
new file mode 100644
index 000000000000..93f3b18f192f
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.zero
+
+// dynarray shall provide support for the special case of construction with a size of zero.
+// In the case that the size is zero, begin() == end() == unique value.
+// The return value of data() is unspecified.
+// The effect of calling front() or back() for a zero-sized dynarray is undefined.
+
+
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void test ( ) {
+ typedef dynarray<T> dynA;
+
+ dynA d1 ( 0 );
+ assert ( d1.size() == 0 );
+ assert ( d1.begin() == d1.end ());
+ }
+
+int main()
+{
+ test<int> ();
+ test<double> ();
+ test<std::complex<double>> ();
+ test<std::string> ();
+}
+#else
+int main() {}
+#endif
diff --git a/test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp
new file mode 100644
index 000000000000..db9026aebd84
--- /dev/null
+++ b/test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/ratio>
+
+// Test that <ratio> is included.
+
+#include <experimental/ratio>
+
+#if _LIBCPP_STD_VER > 11
+# ifndef _LIBCPP_RATIO
+# error " <experimental/ratio> must include <ratio>"
+# endif
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/utilities/ratio/version.pass.cpp b/test/libcxx/experimental/utilities/ratio/version.pass.cpp
new file mode 100644
index 000000000000..8bc583fb6d94
--- /dev/null
+++ b/test/libcxx/experimental/utilities/ratio/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/ratio>
+
+#include <experimental/ratio>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp
new file mode 100644
index 000000000000..88c7458395d4
--- /dev/null
+++ b/test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/system_error>
+
+#include <experimental/system_error>
+
+#if _LIBCPP_STD_VER > 11
+# ifndef _LIBCPP_SYSTEM_ERROR
+# error "<experimental/system_error> must include <system_error>"
+# endif
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/utilities/syserror/version.pass.cpp b/test/libcxx/experimental/utilities/syserror/version.pass.cpp
new file mode 100644
index 000000000000..35f6a59c3876
--- /dev/null
+++ b/test/libcxx/experimental/utilities/syserror/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/system_error>
+
+#include <experimental/system_error>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp
new file mode 100644
index 000000000000..ad4a79105b0b
--- /dev/null
+++ b/test/libcxx/experimental/utilities/time/header.chrono.synop/includes.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/chrono>
+
+#include <experimental/chrono>
+
+#if _LIBCPP_STD_VER > 11
+# ifndef _LIBCPP_CHRONO
+# error "<experimental/chrono> must include <chrono>"
+# endif
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/utilities/time/version.pass.cpp b/test/libcxx/experimental/utilities/time/version.pass.cpp
new file mode 100644
index 000000000000..be97466f37c0
--- /dev/null
+++ b/test/libcxx/experimental/utilities/time/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/chrono>
+
+#include <experimental/chrono>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
new file mode 100644
index 000000000000..544ddfb269f2
--- /dev/null
+++ b/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/tuple>
+
+#include <experimental/tuple>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+# ifndef _LIBCPP_TUPLE
+# error "<experimental/tuple> must include <tuple>"
+# endif
+#endif /* _LIBCPP_STD_VER > 11 */
+}
diff --git a/test/libcxx/experimental/utilities/tuple/version.pass.cpp b/test/libcxx/experimental/utilities/tuple/version.pass.cpp
new file mode 100644
index 000000000000..5a3fd2e39647
--- /dev/null
+++ b/test/libcxx/experimental/utilities/tuple/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/tuple>
+
+#include <experimental/tuple>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/selftest/not_test.sh.cpp b/test/libcxx/selftest/not_test.sh.cpp
new file mode 100644
index 000000000000..5b8348f0eecd
--- /dev/null
+++ b/test/libcxx/selftest/not_test.sh.cpp
@@ -0,0 +1,17 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// RUN: %build
+// RUN: not %run
+
+int main()
+{
+ return 1;
+}
diff --git a/test/libcxx/selftest/test.fail.cpp b/test/libcxx/selftest/test.fail.cpp
new file mode 100644
index 000000000000..2ad608bab260
--- /dev/null
+++ b/test/libcxx/selftest/test.fail.cpp
@@ -0,0 +1,11 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#error This test should not compile.
diff --git a/test/libcxx/selftest/test.pass.cpp b/test/libcxx/selftest/test.pass.cpp
new file mode 100644
index 000000000000..9a59227abdd9
--- /dev/null
+++ b/test/libcxx/selftest/test.pass.cpp
@@ -0,0 +1,13 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/libcxx/selftest/test.sh.cpp b/test/libcxx/selftest/test.sh.cpp
new file mode 100644
index 000000000000..14dc2db8018b
--- /dev/null
+++ b/test/libcxx/selftest/test.sh.cpp
@@ -0,0 +1,16 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// RUN: %build
+// RUN: %run
+
+int main()
+{
+}
diff --git a/test/libcxx/selftest/test_macros.pass.cpp b/test/libcxx/selftest/test_macros.pass.cpp
new file mode 100644
index 000000000000..2c8ed4f454a7
--- /dev/null
+++ b/test/libcxx/selftest/test_macros.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Test the "test_macros.h" header.
+#include "test_macros.h"
+
+#ifndef TEST_STD_VER
+#error TEST_STD_VER must be defined
+#endif
+
+#ifndef TEST_DECLTYPE
+#error TEST_DECLTYPE must be defined
+#endif
+
+#ifndef TEST_NOEXCEPT
+#error TEST_NOEXCEPT must be defined
+#endif
+
+#ifndef TEST_STATIC_ASSERT
+#error TEST_STATIC_ASSERT must be defined
+#endif
+
+template <class T, class U>
+struct is_same { enum { value = 0 }; };
+
+template <class T>
+struct is_same<T, T> { enum { value = 1 }; };
+
+int foo() { return 0; }
+
+void test_noexcept() TEST_NOEXCEPT
+{
+}
+
+void test_decltype()
+{
+ typedef TEST_DECLTYPE(foo()) MyType;
+ TEST_STATIC_ASSERT((is_same<MyType, int>::value), "is same");
+}
+
+void test_static_assert()
+{
+ TEST_STATIC_ASSERT((is_same<int, int>::value), "is same");
+ TEST_STATIC_ASSERT((!is_same<int, long>::value), "not same");
+}
+
+int main()
+{
+ test_noexcept();
+ test_decltype();
+ test_static_assert();
+}
diff --git a/test/libcxx/test/__init__.py b/test/libcxx/test/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/test/libcxx/test/__init__.py
diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py
new file mode 100644
index 000000000000..09fbf66dbba0
--- /dev/null
+++ b/test/libcxx/test/config.py
@@ -0,0 +1,709 @@
+import importlib
+import locale
+import os
+import platform
+import pkgutil
+import re
+import shlex
+import sys
+
+import lit.Test # pylint: disable=import-error,no-name-in-module
+import lit.util # pylint: disable=import-error,no-name-in-module
+
+from libcxx.test.format import LibcxxTestFormat
+from libcxx.compiler import CXXCompiler
+from libcxx.test.executor import *
+from libcxx.test.tracing import *
+
+def loadSiteConfig(lit_config, config, param_name, env_name):
+ # We haven't loaded the site specific configuration (the user is
+ # probably trying to run on a test file directly, and either the site
+ # configuration hasn't been created by the build system, or we are in an
+ # out-of-tree build situation).
+ site_cfg = lit_config.params.get(param_name,
+ os.environ.get(env_name))
+ if not site_cfg:
+ lit_config.warning('No site specific configuration file found!'
+ ' Running the tests in the default configuration.')
+ elif not os.path.isfile(site_cfg):
+ lit_config.fatal(
+ "Specified site configuration file does not exist: '%s'" %
+ site_cfg)
+ else:
+ lit_config.note('using site specific configuration at %s' % site_cfg)
+ ld_fn = lit_config.load_config
+
+ # Null out the load_config function so that lit.site.cfg doesn't
+ # recursively load a config even if it tries.
+ # TODO: This is one hell of a hack. Fix it.
+ def prevent_reload_fn(*args, **kwargs):
+ pass
+ lit_config.load_config = prevent_reload_fn
+ ld_fn(config, site_cfg)
+ lit_config.load_config = ld_fn
+
+
+class Configuration(object):
+ # pylint: disable=redefined-outer-name
+ def __init__(self, lit_config, config):
+ self.lit_config = lit_config
+ self.config = config
+ self.cxx = None
+ self.libcxx_src_root = None
+ self.libcxx_obj_root = None
+ self.cxx_library_root = None
+ self.abi_library_root = None
+ self.env = {}
+ self.use_target = False
+ self.use_system_cxx_lib = False
+ self.use_clang_verify = False
+ self.long_tests = None
+ self.execute_external = False
+
+ def get_lit_conf(self, name, default=None):
+ val = self.lit_config.params.get(name, None)
+ if val is None:
+ val = getattr(self.config, name, None)
+ if val is None:
+ val = default
+ return val
+
+ def get_lit_bool(self, name, default=None):
+ conf = self.get_lit_conf(name)
+ if conf is None:
+ return default
+ if conf.lower() in ('1', 'true'):
+ return True
+ if conf.lower() in ('', '0', 'false'):
+ return False
+ self.lit_config.fatal(
+ "parameter '{}' should be true or false".format(name))
+
+ def configure(self):
+ self.configure_executor()
+ self.configure_target_info()
+ self.configure_cxx()
+ self.configure_triple()
+ self.configure_src_root()
+ self.configure_obj_root()
+ self.configure_cxx_library_root()
+ self.configure_use_system_cxx_lib()
+ self.configure_use_clang_verify()
+ self.configure_execute_external()
+ self.configure_ccache()
+ self.configure_compile_flags()
+ self.configure_link_flags()
+ self.configure_env()
+ self.configure_color_diagnostics()
+ self.configure_debug_mode()
+ self.configure_warnings()
+ self.configure_sanitizer()
+ self.configure_coverage()
+ self.configure_substitutions()
+ self.configure_features()
+
+ def print_config_info(self):
+ # Print the final compile and link flags.
+ self.lit_config.note('Using compiler: %s' % self.cxx.path)
+ self.lit_config.note('Using flags: %s' % self.cxx.flags)
+ self.lit_config.note('Using compile flags: %s'
+ % self.cxx.compile_flags)
+ self.lit_config.note('Using link flags: %s' % self.cxx.link_flags)
+ # Print as list to prevent "set([...])" from being printed.
+ self.lit_config.note('Using available_features: %s' %
+ list(self.config.available_features))
+ self.lit_config.note('Using environment: %r' % self.env)
+
+ def get_test_format(self):
+ return LibcxxTestFormat(
+ self.cxx,
+ self.use_clang_verify,
+ self.execute_external,
+ self.executor,
+ exec_env=self.env)
+
+ def configure_executor(self):
+ exec_str = self.get_lit_conf('executor', "None")
+ te = eval(exec_str)
+ if te:
+ self.lit_config.note("Using executor: %r" % exec_str)
+ if self.lit_config.useValgrind:
+ # We have no way of knowing where in the chain the
+ # ValgrindExecutor is supposed to go. It is likely
+ # that the user wants it at the end, but we have no
+ # way of getting at that easily.
+ selt.lit_config.fatal("Cannot infer how to create a Valgrind "
+ " executor.")
+ else:
+ te = LocalExecutor()
+ if self.lit_config.useValgrind:
+ te = ValgrindExecutor(self.lit_config.valgrindArgs, te)
+ self.executor = te
+
+ def configure_target_info(self):
+ default = "libcxx.test.target_info.LocalTI"
+ info_str = self.get_lit_conf('target_info', default)
+ mod_path, _, info = info_str.rpartition('.')
+ mod = importlib.import_module(mod_path)
+ self.target_info = getattr(mod, info)()
+ if info_str != default:
+ self.lit_config.note("inferred target_info as: %r" % info_str)
+
+ def configure_cxx(self):
+ # Gather various compiler parameters.
+ cxx = self.get_lit_conf('cxx_under_test')
+
+ # If no specific cxx_under_test was given, attempt to infer it as
+ # clang++.
+ if cxx is None:
+ clangxx = lit.util.which('clang++',
+ self.config.environment['PATH'])
+ if clangxx:
+ cxx = clangxx
+ self.lit_config.note(
+ "inferred cxx_under_test as: %r" % cxx)
+ if not cxx:
+ self.lit_config.fatal('must specify user parameter cxx_under_test '
+ '(e.g., --param=cxx_under_test=clang++)')
+ self.cxx = CXXCompiler(cxx)
+ cxx_type = self.cxx.type
+ if cxx_type is not None:
+ assert self.cxx.version is not None
+ maj_v, min_v, _ = self.cxx.version
+ self.config.available_features.add(cxx_type)
+ self.config.available_features.add('%s-%s.%s' % (
+ cxx_type, maj_v, min_v))
+
+ def configure_src_root(self):
+ self.libcxx_src_root = self.get_lit_conf(
+ 'libcxx_src_root', os.path.dirname(self.config.test_source_root))
+
+ def configure_obj_root(self):
+ self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
+
+ def configure_cxx_library_root(self):
+ self.cxx_library_root = self.get_lit_conf('cxx_library_root',
+ self.libcxx_obj_root)
+
+ def configure_use_system_cxx_lib(self):
+ # This test suite supports testing against either the system library or
+ # the locally built one; the former mode is useful for testing ABI
+ # compatibility between the current headers and a shipping dynamic
+ # library.
+ self.use_system_cxx_lib = self.get_lit_bool('use_system_cxx_lib')
+ if self.use_system_cxx_lib is None:
+ # Default to testing against the locally built libc++ library.
+ self.use_system_cxx_lib = False
+ self.lit_config.note(
+ "inferred use_system_cxx_lib as: %r" % self.use_system_cxx_lib)
+
+ def configure_use_clang_verify(self):
+ '''If set, run clang with -verify on failing tests.'''
+ self.use_clang_verify = self.get_lit_bool('use_clang_verify')
+ if self.use_clang_verify is None:
+ # NOTE: We do not test for the -verify flag directly because
+ # -verify will always exit with non-zero on an empty file.
+ self.use_clang_verify = self.cxx.hasCompileFlag(
+ ['-Xclang', '-verify-ignore-unexpected'])
+ self.lit_config.note(
+ "inferred use_clang_verify as: %r" % self.use_clang_verify)
+
+ def configure_execute_external(self):
+ # Choose between lit's internal shell pipeline runner and a real shell.
+ # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as the
+ # default value. Otherwise we default to internal on Windows and
+ # external elsewhere, as bash on Windows is usually very slow.
+ use_lit_shell_default = os.environ.get('LIT_USE_INTERNAL_SHELL')
+ if use_lit_shell_default is not None:
+ use_lit_shell_default = use_lit_shell_default != '0'
+ else:
+ use_lit_shell_default = sys.platform == 'win32'
+ # Check for the command line parameter using the default value if it is
+ # not present.
+ use_lit_shell = self.get_lit_bool('use_lit_shell',
+ use_lit_shell_default)
+ self.execute_external = not use_lit_shell
+
+ def configure_ccache(self):
+ use_ccache_default = os.environ.get('LIBCXX_USE_CCACHE') is not None
+ use_ccache = self.get_lit_bool('use_ccache', use_ccache_default)
+ if use_ccache:
+ self.cxx.use_ccache = True
+ self.lit_config.note('enabling ccache')
+
+ def configure_features(self):
+ additional_features = self.get_lit_conf('additional_features')
+ if additional_features:
+ for f in additional_features.split(','):
+ self.config.available_features.add(f.strip())
+
+ # Figure out which of the required locales we support
+ locales = {
+ 'Darwin': {
+ 'en_US.UTF-8': 'en_US.UTF-8',
+ 'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
+ 'fr_FR.UTF-8': 'fr_FR.UTF-8',
+ 'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
+ 'ru_RU.UTF-8': 'ru_RU.UTF-8',
+ 'zh_CN.UTF-8': 'zh_CN.UTF-8',
+ },
+ 'FreeBSD': {
+ 'en_US.UTF-8': 'en_US.UTF-8',
+ 'cs_CZ.ISO8859-2': 'cs_CZ.ISO8859-2',
+ 'fr_FR.UTF-8': 'fr_FR.UTF-8',
+ 'fr_CA.ISO8859-1': 'fr_CA.ISO8859-1',
+ 'ru_RU.UTF-8': 'ru_RU.UTF-8',
+ 'zh_CN.UTF-8': 'zh_CN.UTF-8',
+ },
+ 'Linux': {
+ 'en_US.UTF-8': 'en_US.UTF-8',
+ 'cs_CZ.ISO8859-2': 'cs_CZ.ISO-8859-2',
+ 'fr_FR.UTF-8': 'fr_FR.UTF-8',
+ 'fr_CA.ISO8859-1': 'fr_CA.ISO-8859-1',
+ 'ru_RU.UTF-8': 'ru_RU.UTF-8',
+ 'zh_CN.UTF-8': 'zh_CN.UTF-8',
+ },
+ 'Windows': {
+ 'en_US.UTF-8': 'English_United States.1252',
+ 'cs_CZ.ISO8859-2': 'Czech_Czech Republic.1250',
+ 'fr_FR.UTF-8': 'French_France.1252',
+ 'fr_CA.ISO8859-1': 'French_Canada.1252',
+ 'ru_RU.UTF-8': 'Russian_Russia.1251',
+ 'zh_CN.UTF-8': 'Chinese_China.936',
+ },
+ }
+
+ target_system = self.target_info.system()
+ target_platform = self.target_info.platform()
+
+ if target_system in locales:
+ default_locale = locale.setlocale(locale.LC_ALL)
+ for feature, loc in locales[target_system].items():
+ try:
+ locale.setlocale(locale.LC_ALL, loc)
+ self.config.available_features.add(
+ 'locale.{0}'.format(feature))
+ except locale.Error:
+ self.lit_config.warning('The locale {0} is not supported by '
+ 'your platform. Some tests will be '
+ 'unsupported.'.format(loc))
+ locale.setlocale(locale.LC_ALL, default_locale)
+ else:
+ # Warn that the user doesn't get any free XFAILs for locale issues
+ self.lit_config.warning("No locales entry for target_system: %s" %
+ target_system)
+
+ # Write an "available feature" that combines the triple when
+ # use_system_cxx_lib is enabled. This is so that we can easily write
+ # XFAIL markers for tests that are known to fail with versions of
+ # libc++ as were shipped with a particular triple.
+ if self.use_system_cxx_lib:
+ self.config.available_features.add(
+ 'with_system_cxx_lib=%s' % self.config.target_triple)
+
+ # Insert the platform name into the available features as a lower case.
+ self.config.available_features.add(target_platform)
+
+ # Some linux distributions have different locale data than others.
+ # Insert the distributions name and name-version into the available
+ # features to allow tests to XFAIL on them.
+ if target_platform == 'linux':
+ name = self.target_info.platform_name()
+ ver = self.target_info.platform_ver()
+ if name:
+ self.config.available_features.add(name)
+ if name and ver:
+ self.config.available_features.add('%s-%s' % (name, ver))
+
+ # Simulator testing can take a really long time for some of these tests
+ # so add a feature check so we can REQUIRES: long_tests in them
+ self.long_tests = self.get_lit_bool('long_tests')
+ if self.long_tests is None:
+ # Default to running long tests.
+ self.long_tests = True
+ self.lit_config.note(
+ "inferred long_tests as: %r" % self.long_tests)
+
+ if self.long_tests:
+ self.config.available_features.add('long_tests')
+
+ # Run a compile test for the -fsized-deallocation flag. This is needed
+ # in test/std/language.support/support.dynamic/new.delete
+ if self.cxx.hasCompileFlag('-fsized-deallocation'):
+ self.config.available_features.add('fsized-deallocation')
+
+ def configure_compile_flags(self):
+ no_default_flags = self.get_lit_bool('no_default_flags', False)
+ if not no_default_flags:
+ self.configure_default_compile_flags()
+ # Configure extra flags
+ compile_flags_str = self.get_lit_conf('compile_flags', '')
+ self.cxx.compile_flags += shlex.split(compile_flags_str)
+
+ def configure_default_compile_flags(self):
+ # Try and get the std version from the command line. Fall back to
+ # default given in lit.site.cfg is not present. If default is not
+ # present then force c++11.
+ std = self.get_lit_conf('std', 'c++11')
+ self.cxx.compile_flags += ['-std={0}'.format(std)]
+ self.config.available_features.add(std)
+ # Configure include paths
+ self.cxx.compile_flags += ['-nostdinc++']
+ self.configure_compile_flags_header_includes()
+ if self.target_info.platform() == 'linux':
+ self.cxx.compile_flags += ['-D__STDC_FORMAT_MACROS',
+ '-D__STDC_LIMIT_MACROS',
+ '-D__STDC_CONSTANT_MACROS']
+ # Configure feature flags.
+ self.configure_compile_flags_exceptions()
+ self.configure_compile_flags_rtti()
+ self.configure_compile_flags_no_global_filesystem_namespace()
+ self.configure_compile_flags_no_stdin()
+ self.configure_compile_flags_no_stdout()
+ enable_32bit = self.get_lit_bool('enable_32bit', False)
+ if enable_32bit:
+ self.cxx.flags += ['-m32']
+ # Configure threading features.
+ enable_threads = self.get_lit_bool('enable_threads', True)
+ enable_monotonic_clock = self.get_lit_bool('enable_monotonic_clock',
+ True)
+ if not enable_threads:
+ self.configure_compile_flags_no_threads()
+ if not enable_monotonic_clock:
+ self.configure_compile_flags_no_monotonic_clock()
+ elif not enable_monotonic_clock:
+ self.lit_config.fatal('enable_monotonic_clock cannot be false when'
+ ' enable_threads is true.')
+ self.configure_compile_flags_no_thread_unsafe_c_functions()
+
+ # Use verbose output for better errors
+ self.cxx.flags += ['-v']
+ sysroot = self.get_lit_conf('sysroot')
+ if sysroot:
+ self.cxx.flags += ['--sysroot', sysroot]
+ gcc_toolchain = self.get_lit_conf('gcc_toolchain')
+ if gcc_toolchain:
+ self.cxx.flags += ['-gcc-toolchain', gcc_toolchain]
+ if self.use_target:
+ self.cxx.flags += ['-target', self.config.target_triple]
+
+ def configure_compile_flags_header_includes(self):
+ support_path = os.path.join(self.libcxx_src_root, 'test/support')
+ self.cxx.compile_flags += ['-I' + support_path]
+ self.cxx.compile_flags += ['-include', os.path.join(support_path, 'nasty_macros.hpp')]
+ libcxx_headers = self.get_lit_conf(
+ 'libcxx_headers', os.path.join(self.libcxx_src_root, 'include'))
+ if not os.path.isdir(libcxx_headers):
+ self.lit_config.fatal("libcxx_headers='%s' is not a directory."
+ % libcxx_headers)
+ self.cxx.compile_flags += ['-I' + libcxx_headers]
+
+ def configure_compile_flags_exceptions(self):
+ enable_exceptions = self.get_lit_bool('enable_exceptions', True)
+ if not enable_exceptions:
+ self.config.available_features.add('libcpp-no-exceptions')
+ self.cxx.compile_flags += ['-fno-exceptions']
+
+ def configure_compile_flags_rtti(self):
+ enable_rtti = self.get_lit_bool('enable_rtti', True)
+ if not enable_rtti:
+ self.config.available_features.add('libcpp-no-rtti')
+ self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
+
+ def configure_compile_flags_no_global_filesystem_namespace(self):
+ enable_global_filesystem_namespace = self.get_lit_bool(
+ 'enable_global_filesystem_namespace', True)
+ if not enable_global_filesystem_namespace:
+ self.config.available_features.add(
+ 'libcpp-has-no-global-filesystem-namespace')
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE']
+
+ def configure_compile_flags_no_stdin(self):
+ enable_stdin = self.get_lit_bool('enable_stdin', True)
+ if not enable_stdin:
+ self.config.available_features.add('libcpp-has-no-stdin')
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDIN']
+
+ def configure_compile_flags_no_stdout(self):
+ enable_stdout = self.get_lit_bool('enable_stdout', True)
+ if not enable_stdout:
+ self.config.available_features.add('libcpp-has-no-stdout')
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDOUT']
+
+ def configure_compile_flags_no_threads(self):
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
+ self.config.available_features.add('libcpp-has-no-threads')
+
+ def configure_compile_flags_no_thread_unsafe_c_functions(self):
+ enable_thread_unsafe_c_functions = self.get_lit_bool(
+ 'enable_thread_unsafe_c_functions', True)
+ if not enable_thread_unsafe_c_functions:
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS']
+ self.config.available_features.add(
+ 'libcpp-has-no-thread-unsafe-c-functions')
+
+ def configure_compile_flags_no_monotonic_clock(self):
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
+ self.config.available_features.add('libcpp-has-no-monotonic-clock')
+
+ def configure_link_flags(self):
+ no_default_flags = self.get_lit_bool('no_default_flags', False)
+ if not no_default_flags:
+ self.cxx.link_flags += ['-nodefaultlibs']
+
+ # Configure library path
+ self.configure_link_flags_cxx_library_path()
+ self.configure_link_flags_abi_library_path()
+
+ # Configure libraries
+ self.configure_link_flags_cxx_library()
+ self.configure_link_flags_abi_library()
+ self.configure_extra_library_flags()
+
+ link_flags_str = self.get_lit_conf('link_flags', '')
+ self.cxx.link_flags += shlex.split(link_flags_str)
+
+ def configure_link_flags_cxx_library_path(self):
+ libcxx_library = self.get_lit_conf('libcxx_library')
+ # Configure libc++ library paths.
+ if libcxx_library is not None:
+ # Check that the given value for libcxx_library is valid.
+ if not os.path.isfile(libcxx_library):
+ self.lit_config.fatal(
+ "libcxx_library='%s' is not a valid file." %
+ libcxx_library)
+ if self.use_system_cxx_lib:
+ self.lit_config.fatal(
+ "Conflicting options: 'libcxx_library' cannot be used "
+ "with 'use_system_cxx_lib=true'")
+ self.cxx.link_flags += ['-Wl,-rpath,' +
+ os.path.dirname(libcxx_library)]
+ elif not self.use_system_cxx_lib and self.cxx_library_root:
+ self.cxx.link_flags += ['-L' + self.cxx_library_root,
+ '-Wl,-rpath,' + self.cxx_library_root]
+
+ def configure_link_flags_abi_library_path(self):
+ # Configure ABI library paths.
+ self.abi_library_root = self.get_lit_conf('abi_library_path')
+ if self.abi_library_root:
+ self.cxx.link_flags += ['-L' + self.abi_library_root,
+ '-Wl,-rpath,' + self.abi_library_root]
+
+ def configure_link_flags_cxx_library(self):
+ libcxx_library = self.get_lit_conf('libcxx_library')
+ if libcxx_library:
+ self.cxx.link_flags += [libcxx_library]
+ else:
+ self.cxx.link_flags += ['-lc++']
+
+ def configure_link_flags_abi_library(self):
+ cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
+ if cxx_abi == 'libstdc++':
+ self.cxx.link_flags += ['-lstdc++']
+ elif cxx_abi == 'libsupc++':
+ self.cxx.link_flags += ['-lsupc++']
+ elif cxx_abi == 'libcxxabi':
+ # Don't link libc++abi explicitly on OS X because the symbols
+ # should be available in libc++ directly.
+ if self.target_info.platform() != 'darwin':
+ self.cxx.link_flags += ['-lc++abi']
+ elif cxx_abi == 'libcxxrt':
+ self.cxx.link_flags += ['-lcxxrt']
+ elif cxx_abi == 'none':
+ pass
+ else:
+ self.lit_config.fatal(
+ 'C++ ABI setting %s unsupported for tests' % cxx_abi)
+
+ def configure_extra_library_flags(self):
+ enable_threads = self.get_lit_bool('enable_threads', True)
+ llvm_unwinder = self.get_lit_bool('llvm_unwinder', False)
+ target_platform = self.target_info.platform()
+ if target_platform == 'darwin':
+ self.cxx.link_flags += ['-lSystem']
+ elif target_platform == 'linux':
+ if not llvm_unwinder:
+ self.cxx.link_flags += ['-lgcc_eh']
+ self.cxx.link_flags += ['-lc', '-lm']
+ if enable_threads:
+ self.cxx.link_flags += ['-lpthread']
+ self.cxx.link_flags += ['-lrt']
+ if llvm_unwinder:
+ self.cxx.link_flags += ['-lunwind', '-ldl']
+ else:
+ self.cxx.link_flags += ['-lgcc_s']
+ elif target_platform.startswith('freebsd'):
+ self.cxx.link_flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
+ else:
+ self.lit_config.fatal("unrecognized system: %r" % target_platform)
+
+ def configure_color_diagnostics(self):
+ use_color = self.get_lit_conf('color_diagnostics')
+ if use_color is None:
+ use_color = os.environ.get('LIBCXX_COLOR_DIAGNOSTICS')
+ if use_color is None:
+ return
+ if use_color != '':
+ self.lit_config.fatal('Invalid value for color_diagnostics "%s".'
+ % use_color)
+ color_flag = '-fdiagnostics-color=always'
+ # Check if the compiler supports the color diagnostics flag. Issue a
+ # warning if it does not since color diagnostics have been requested.
+ if not self.cxx.hasCompileFlag(color_flag):
+ self.lit_config.warning(
+ 'color diagnostics have been requested but are not supported '
+ 'by the compiler')
+ else:
+ self.cxx.flags += [color_flag]
+
+ def configure_debug_mode(self):
+ debug_level = self.get_lit_conf('debug_level', None)
+ if not debug_level:
+ return
+ if debug_level not in ['0', '1']:
+ self.lit_config.fatal('Invalid value for debug_level "%s".'
+ % debug_level)
+ self.cxx.compile_flags += ['-D_LIBCPP_DEBUG=%s' % debug_level]
+
+ def configure_warnings(self):
+ enable_warnings = self.get_lit_bool('enable_warnings', False)
+ if enable_warnings:
+ self.cxx.compile_flags += ['-Wsystem-headers', '-Wall', '-Werror']
+ if ('clang' in self.config.available_features or
+ 'apple-clang' in self.config.available_features):
+ self.cxx.compile_flags += ['-Wno-user-defined-literals']
+
+ def configure_sanitizer(self):
+ san = self.get_lit_conf('use_sanitizer', '').strip()
+ if san:
+ # Search for llvm-symbolizer along the compiler path first
+ # and then along the PATH env variable.
+ symbolizer_search_paths = os.environ.get('PATH', '')
+ cxx_path = lit.util.which(self.cxx.path)
+ if cxx_path is not None:
+ symbolizer_search_paths = (
+ os.path.dirname(cxx_path) +
+ os.pathsep + symbolizer_search_paths)
+ llvm_symbolizer = lit.util.which('llvm-symbolizer',
+ symbolizer_search_paths)
+ # Setup the sanitizer compile flags
+ self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
+ if self.target_info.platform() == 'linux':
+ self.cxx.link_flags += ['-ldl']
+ if san == 'Address':
+ self.cxx.flags += ['-fsanitize=address']
+ if llvm_symbolizer is not None:
+ self.env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
+ self.config.available_features.add('asan')
+ self.config.available_features.add('sanitizer-new-delete')
+ elif san == 'Memory' or san == 'MemoryWithOrigins':
+ self.cxx.flags += ['-fsanitize=memory']
+ if san == 'MemoryWithOrigins':
+ self.cxx.compile_flags += [
+ '-fsanitize-memory-track-origins']
+ if llvm_symbolizer is not None:
+ self.env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
+ self.config.available_features.add('msan')
+ self.config.available_features.add('sanitizer-new-delete')
+ elif san == 'Undefined':
+ self.cxx.flags += ['-fsanitize=undefined',
+ '-fno-sanitize=vptr,function',
+ '-fno-sanitize-recover']
+ self.cxx.compile_flags += ['-O3']
+ self.config.available_features.add('ubsan')
+ elif san == 'Thread':
+ self.cxx.flags += ['-fsanitize=thread']
+ self.config.available_features.add('tsan')
+ self.config.available_features.add('sanitizer-new-delete')
+ else:
+ self.lit_config.fatal('unsupported value for '
+ 'use_sanitizer: {0}'.format(san))
+
+ def configure_coverage(self):
+ self.generate_coverage = self.get_lit_bool('generate_coverage', False)
+ if self.generate_coverage:
+ self.cxx.flags += ['-g', '--coverage']
+ self.cxx.compile_flags += ['-O0']
+
+ def configure_substitutions(self):
+ sub = self.config.substitutions
+ # Configure compiler substitions
+ sub.append(('%cxx', self.cxx.path))
+ # Configure flags substitutions
+ flags_str = ' '.join(self.cxx.flags)
+ compile_flags_str = ' '.join(self.cxx.compile_flags)
+ link_flags_str = ' '.join(self.cxx.link_flags)
+ all_flags = '%s %s %s' % (flags_str, compile_flags_str, link_flags_str)
+ sub.append(('%flags', flags_str))
+ sub.append(('%compile_flags', compile_flags_str))
+ sub.append(('%link_flags', link_flags_str))
+ sub.append(('%all_flags', all_flags))
+ # Add compile and link shortcuts
+ compile_str = (self.cxx.path + ' -o %t.o %s -c ' + flags_str
+ + compile_flags_str)
+ link_str = (self.cxx.path + ' -o %t.exe %t.o ' + flags_str
+ + link_flags_str)
+ assert type(link_str) is str
+ build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
+ sub.append(('%compile', compile_str))
+ sub.append(('%link', link_str))
+ sub.append(('%build', build_str))
+ # Configure exec prefix substitutions.
+ exec_env_str = 'env ' if len(self.env) != 0 else ''
+ for k, v in self.env.items():
+ exec_env_str += ' %s=%s' % (k, v)
+ # Configure run env substitution.
+ exec_str = ''
+ if self.lit_config.useValgrind:
+ exec_str = ' '.join(self.lit_config.valgrindArgs) + exec_env_str
+ sub.append(('%exec', exec_str))
+ # Configure run shortcut
+ sub.append(('%run', exec_str + ' %t.exe'))
+ # Configure not program substitions
+ not_py = os.path.join(self.libcxx_src_root, 'utils', 'not', 'not.py')
+ not_str = '%s %s' % (sys.executable, not_py)
+ sub.append(('not', not_str))
+
+ def configure_triple(self):
+ # Get or infer the target triple.
+ self.config.target_triple = self.get_lit_conf('target_triple')
+ self.use_target = bool(self.config.target_triple)
+ # If no target triple was given, try to infer it from the compiler
+ # under test.
+ if not self.use_target:
+ target_triple = self.cxx.getTriple()
+ # Drop sub-major version components from the triple, because the
+ # current XFAIL handling expects exact matches for feature checks.
+ # Example: x86_64-apple-darwin14.0.0 -> x86_64-apple-darwin14
+ # The 5th group handles triples greater than 3 parts
+ # (ex x86_64-pc-linux-gnu).
+ target_triple = re.sub(r'([^-]+)-([^-]+)-([^.]+)([^-]*)(.*)',
+ r'\1-\2-\3\5', target_triple)
+ # linux-gnu is needed in the triple to properly identify linuxes
+ # that use GLIBC. Handle redhat and opensuse triples as special
+ # cases and append the missing `-gnu` portion.
+ if (target_triple.endswith('redhat-linux') or
+ target_triple.endswith('suse-linux')):
+ target_triple += '-gnu'
+ self.config.target_triple = target_triple
+ self.lit_config.note(
+ "inferred target_triple as: %r" % self.config.target_triple)
+
+ def configure_env(self):
+ if self.target_info.platform() == 'darwin':
+ library_paths = []
+ # Configure the library path for libc++
+ libcxx_library = self.get_lit_conf('libcxx_library')
+ if self.use_system_cxx_lib:
+ pass
+ elif libcxx_library:
+ library_paths += [os.path.dirname(libcxx_library)]
+ elif self.cxx_library_root:
+ library_paths += [self.cxx_library_root]
+ # Configure the abi library path
+ if self.abi_library_root:
+ library_paths += [self.abi_library_root]
+ if library_paths:
+ self.env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
diff --git a/test/libcxx/test/executor.py b/test/libcxx/test/executor.py
new file mode 100644
index 000000000000..f0356ceca784
--- /dev/null
+++ b/test/libcxx/test/executor.py
@@ -0,0 +1,191 @@
+import os
+
+from libcxx.test import tracing
+
+from lit.util import executeCommand # pylint: disable=import-error
+
+
+class Executor(object):
+ def run(self, exe_path, cmd, local_cwd, file_deps=None, env=None):
+ """Execute a command.
+ Be very careful not to change shared state in this function.
+ Executor objects are shared between python processes in `lit -jN`.
+ Args:
+ exe_path: str: Local path to the executable to be run
+ cmd: [str]: subprocess.call style command
+ local_cwd: str: Local path to the working directory
+ file_deps: [str]: Files required by the test
+ env: {str: str}: Environment variables to execute under
+ Returns:
+ cmd, out, err, exitCode
+ """
+ raise NotImplementedError
+
+
+class LocalExecutor(Executor):
+ def __init__(self):
+ super(LocalExecutor, self).__init__()
+
+ def run(self, exe_path, cmd=None, work_dir='.', file_deps=None, env=None):
+ cmd = cmd or [exe_path]
+ env_cmd = []
+ if env:
+ env_cmd += ['env']
+ env_cmd += ['%s=%s' % (k, v) for k, v in env.items()]
+ if work_dir == '.':
+ work_dir = os.getcwd()
+ out, err, rc = executeCommand(env_cmd + cmd, cwd=work_dir)
+ return (env_cmd + cmd, out, err, rc)
+
+
+class PrefixExecutor(Executor):
+ """Prefix an executor with some other command wrapper.
+
+ Most useful for setting ulimits on commands, or running an emulator like
+ qemu and valgrind.
+ """
+ def __init__(self, commandPrefix, chain):
+ super(PrefixExecutor, self).__init__()
+
+ self.commandPrefix = commandPrefix
+ self.chain = chain
+
+ def run(self, exe_path, cmd=None, work_dir='.', file_deps=None, env=None):
+ cmd = cmd or [exe_path]
+ return self.chain.run(exe_path, self.commandPrefix + cmd, work_dir,
+ file_deps, env=env)
+
+
+class PostfixExecutor(Executor):
+ """Postfix an executor with some args."""
+ def __init__(self, commandPostfix, chain):
+ super(PostfixExecutor, self).__init__()
+
+ self.commandPostfix = commandPostfix
+ self.chain = chain
+
+ def run(self, exe_path, cmd=None, work_dir='.', file_deps=None, env=None):
+ cmd = cmd or [exe_path]
+ return self.chain.run(cmd + self.commandPostfix, work_dir, file_deps,
+ env=env)
+
+
+
+class TimeoutExecutor(PrefixExecutor):
+ """Execute another action under a timeout.
+
+ Deprecated. http://reviews.llvm.org/D6584 adds timeouts to LIT.
+ """
+ def __init__(self, duration, chain):
+ super(TimeoutExecutor, self).__init__(
+ ['timeout', duration], chain)
+
+
+class RemoteExecutor(Executor):
+ def __init__(self):
+ self.local_run = executeCommand
+
+ def remote_temp_dir(self):
+ return self._remote_temp(True)
+
+ def remote_temp_file(self):
+ return self._remote_temp(False)
+
+ def _remote_temp(self, is_dir):
+ raise NotImplementedError()
+
+ def copy_in(self, local_srcs, remote_dsts):
+ # This could be wrapped up in a tar->scp->untar for performance
+ # if there are lots of files to be copied/moved
+ for src, dst in zip(local_srcs, remote_dsts):
+ self._copy_in_file(src, dst)
+
+ def _copy_in_file(self, src, dst):
+ raise NotImplementedError()
+
+ def delete_remote(self, remote):
+ try:
+ self._execute_command_remote(['rm', '-rf', remote])
+ except OSError:
+ # TODO: Log failure to delete?
+ pass
+
+ def run(self, exe_path, cmd=None, work_dir='.', file_deps=None, env=None):
+ target_exe_path = None
+ target_cwd = None
+ try:
+ target_cwd = self.remote_temp_dir()
+ target_exe_path = os.path.join(target_cwd, 'libcxx_test.exe')
+ if cmd:
+ # Replace exe_path with target_exe_path.
+ cmd = [c if c != exe_path else target_exe_path for c in cmd]
+ else:
+ cmd = [target_exe_path]
+
+ srcs = [exe_path]
+ dsts = [target_exe_path]
+ if file_deps is not None:
+ dev_paths = [os.path.join(target_cwd, os.path.basename(f))
+ for f in file_deps]
+ srcs.extend(file_deps)
+ dsts.extend(dev_paths)
+ self.copy_in(srcs, dsts)
+ # TODO(jroelofs): capture the copy_in and delete_remote commands,
+ # and conjugate them with '&&'s around the first tuple element
+ # returned here:
+ return self._execute_command_remote(cmd, target_cwd, env)
+ finally:
+ if target_cwd:
+ self.delete_remote(target_cwd)
+
+ def _execute_command_remote(self, cmd, remote_work_dir='.', env=None):
+ raise NotImplementedError()
+
+
+class SSHExecutor(RemoteExecutor):
+ def __init__(self, host, username=None):
+ super(SSHExecutor, self).__init__()
+
+ self.user_prefix = username + '@' if username else ''
+ self.host = host
+ self.scp_command = 'scp'
+ self.ssh_command = 'ssh'
+
+ # TODO(jroelofs): switch this on some -super-verbose-debug config flag
+ if False:
+ self.local_run = tracing.trace_function(
+ self.local_run, log_calls=True, log_results=True,
+ label='ssh_local')
+
+ def _remote_temp(self, is_dir):
+ # TODO: detect what the target system is, and use the correct
+ # mktemp command for it. (linux and darwin differ here, and I'm
+ # sure windows has another way to do it)
+
+ # Not sure how to do suffix on osx yet
+ dir_arg = '-d' if is_dir else ''
+ cmd = 'mktemp -q {} /tmp/libcxx.XXXXXXXXXX'.format(dir_arg)
+ temp_path, err, exitCode = self._execute_command_remote([cmd])
+ temp_path = temp_path.strip()
+ if exitCode != 0:
+ raise RuntimeError(err)
+ return temp_path
+
+ def _copy_in_file(self, src, dst):
+ scp = self.scp_command
+ remote = self.host
+ remote = self.user_prefix + remote
+ cmd = [scp, '-p', src, remote + ':' + dst]
+ self.local_run(cmd)
+
+ def _execute_command_remote(self, cmd, remote_work_dir='.', env=None):
+ remote = self.user_prefix + self.host
+ ssh_cmd = [self.ssh_command, '-oBatchMode=yes', remote]
+ if env:
+ env_cmd = ['env'] + ['%s=%s' % (k, v) for k, v in env.items()]
+ else:
+ env_cmd = []
+ remote_cmd = ' '.join(env_cmd + cmd)
+ if remote_work_dir != '.':
+ remote_cmd = 'cd ' + remote_work_dir + ' && ' + remote_cmd
+ return self.local_run(ssh_cmd + [remote_cmd])
diff --git a/test/libcxx/test/format.py b/test/libcxx/test/format.py
new file mode 100644
index 000000000000..238dcdb29af7
--- /dev/null
+++ b/test/libcxx/test/format.py
@@ -0,0 +1,163 @@
+import errno
+import os
+import time
+
+import lit.Test # pylint: disable=import-error
+import lit.TestRunner # pylint: disable=import-error
+import lit.util # pylint: disable=import-error
+
+from libcxx.test.executor import LocalExecutor as LocalExecutor
+import libcxx.util
+
+
+class LibcxxTestFormat(object):
+ """
+ Custom test format handler for use with the test format use by libc++.
+
+ Tests fall into two categories:
+ FOO.pass.cpp - Executable test which should compile, run, and exit with
+ code 0.
+ FOO.fail.cpp - Negative test case which is expected to fail compilation.
+ FOO.sh.cpp - A test that uses LIT's ShTest format.
+ """
+
+ def __init__(self, cxx, use_verify_for_fail, execute_external,
+ executor, exec_env):
+ self.cxx = cxx
+ self.use_verify_for_fail = use_verify_for_fail
+ self.execute_external = execute_external
+ self.executor = executor
+ self.exec_env = dict(exec_env)
+
+ # TODO: Move this into lit's FileBasedTest
+ def getTestsInDirectory(self, testSuite, path_in_suite,
+ litConfig, localConfig):
+ source_path = testSuite.getSourcePath(path_in_suite)
+ for filename in os.listdir(source_path):
+ # Ignore dot files and excluded tests.
+ if filename.startswith('.') or filename in localConfig.excludes:
+ continue
+
+ filepath = os.path.join(source_path, filename)
+ if not os.path.isdir(filepath):
+ if any([filename.endswith(ext)
+ for ext in localConfig.suffixes]):
+ yield lit.Test.Test(testSuite, path_in_suite + (filename,),
+ localConfig)
+
+ def execute(self, test, lit_config):
+ while True:
+ try:
+ return self._execute(test, lit_config)
+ except OSError as oe:
+ if oe.errno != errno.ETXTBSY:
+ raise
+ time.sleep(0.1)
+
+ def _execute(self, test, lit_config):
+ name = test.path_in_suite[-1]
+ is_sh_test = name.endswith('.sh.cpp')
+ is_pass_test = name.endswith('.pass.cpp')
+ is_fail_test = name.endswith('.fail.cpp')
+
+ if test.config.unsupported:
+ return (lit.Test.UNSUPPORTED,
+ "A lit.local.cfg marked this unsupported")
+
+ res = lit.TestRunner.parseIntegratedTestScript(
+ test, require_script=is_sh_test)
+ # Check if a result for the test was returned. If so return that
+ # result.
+ if isinstance(res, lit.Test.Result):
+ return res
+ if lit_config.noExecute:
+ return lit.Test.Result(lit.Test.PASS)
+ # res is not an instance of lit.test.Result. Expand res into its parts.
+ script, tmpBase, execDir = res
+ # Check that we don't have run lines on tests that don't support them.
+ if not is_sh_test and len(script) != 0:
+ lit_config.fatal('Unsupported RUN line found in test %s' % name)
+
+ # Dispatch the test based on its suffix.
+ if is_sh_test:
+ if not isinstance(self.executor, LocalExecutor):
+ # We can't run ShTest tests with a executor yet.
+ # For now, bail on trying to run them
+ return lit.Test.UNSUPPORTED, 'ShTest format not yet supported'
+ return lit.TestRunner._runShTest(test, lit_config,
+ self.execute_external, script,
+ tmpBase, execDir)
+ elif is_fail_test:
+ return self._evaluate_fail_test(test)
+ elif is_pass_test:
+ return self._evaluate_pass_test(test, tmpBase, execDir, lit_config)
+ else:
+ # No other test type is supported
+ assert False
+
+ def _clean(self, exec_path): # pylint: disable=no-self-use
+ libcxx.util.cleanFile(exec_path)
+
+ def _evaluate_pass_test(self, test, tmpBase, execDir, lit_config):
+ source_path = test.getSourcePath()
+ exec_path = tmpBase + '.exe'
+ object_path = tmpBase + '.o'
+ # Create the output directory if it does not already exist.
+ lit.util.mkdir_p(os.path.dirname(tmpBase))
+ try:
+ # Compile the test
+ cmd, out, err, rc = self.cxx.compileLinkTwoSteps(
+ source_path, out=exec_path, object_file=object_path,
+ cwd=execDir)
+ compile_cmd = cmd
+ if rc != 0:
+ report = libcxx.util.makeReport(cmd, out, err, rc)
+ report += "Compilation failed unexpectedly!"
+ return lit.Test.FAIL, report
+ # Run the test
+ local_cwd = os.path.dirname(source_path)
+ env = None
+ if self.exec_env:
+ env = self.exec_env
+ # TODO: Only list actually needed files in file_deps.
+ # Right now we just mark all of the .dat files in the same
+ # directory as dependencies, but it's likely less than that. We
+ # should add a `// FILE-DEP: foo.dat` to each test to track this.
+ data_files = [os.path.join(local_cwd, f)
+ for f in os.listdir(local_cwd) if f.endswith('.dat')]
+ cmd, out, err, rc = self.executor.run(exec_path, [exec_path],
+ local_cwd, data_files, env)
+ if rc != 0:
+ report = libcxx.util.makeReport(cmd, out, err, rc)
+ report = "Compiled With: %s\n%s" % (compile_cmd, report)
+ report += "Compiled test failed unexpectedly!"
+ return lit.Test.FAIL, report
+ return lit.Test.PASS, ''
+ finally:
+ # Note that cleanup of exec_file happens in `_clean()`. If you
+ # override this, cleanup is your reponsibility.
+ libcxx.util.cleanFile(object_path)
+ self._clean(exec_path)
+
+ def _evaluate_fail_test(self, test):
+ source_path = test.getSourcePath()
+ with open(source_path, 'r') as f:
+ contents = f.read()
+ verify_tags = ['expected-note', 'expected-remark', 'expected-warning',
+ 'expected-error', 'expected-no-diagnostics']
+ use_verify = self.use_verify_for_fail and \
+ any([tag in contents for tag in verify_tags])
+ extra_flags = []
+ if use_verify:
+ extra_flags += ['-Xclang', '-verify',
+ '-Xclang', '-verify-ignore-unexpected=note']
+ cmd, out, err, rc = self.cxx.compile(source_path, out=os.devnull,
+ flags=extra_flags)
+ expected_rc = 0 if use_verify else 1
+ if rc == expected_rc:
+ return lit.Test.PASS, ''
+ else:
+ report = libcxx.util.makeReport(cmd, out, err, rc)
+ report_msg = ('Expected compilation to fail!' if not use_verify else
+ 'Expected compilation using verify to pass!')
+ return lit.Test.FAIL, report + report_msg + '\n'
diff --git a/test/libcxx/test/target_info.py b/test/libcxx/test/target_info.py
new file mode 100644
index 000000000000..a61737786896
--- /dev/null
+++ b/test/libcxx/test/target_info.py
@@ -0,0 +1,55 @@
+import locale
+import platform
+import sys
+
+class TargetInfo(object):
+ def platform(self):
+ raise NotImplementedError
+
+ def system(self):
+ raise NotImplementedError
+
+ def platform_ver(self):
+ raise NotImplementedError
+
+ def platform_name(self):
+ raise NotImplementedError
+
+ def supports_locale(self, loc):
+ raise NotImplementedError
+
+
+class LocalTI(TargetInfo):
+ def platform(self):
+ platform_name = sys.platform.lower().strip()
+ # Strip the '2' from linux2.
+ if platform_name.startswith('linux'):
+ platform_name = 'linux'
+ return platform_name
+
+ def system(self):
+ return platform.system()
+
+ def platform_name(self):
+ if self.platform() == 'linux':
+ name, _, _ = platform.linux_distribution()
+ name = name.lower().strip()
+ if name:
+ return name
+ return None
+
+ def platform_ver(self):
+ if self.platform() == 'linux':
+ _, ver, _ = platform.linux_distribution()
+ ver = ver.lower().strip()
+ if ver:
+ return ver
+ return None
+
+ def supports_locale(self, loc):
+ try:
+ locale.setlocale(locale.LC_ALL, loc)
+ return True
+ except locale.Error:
+ return False
+
diff --git a/test/libcxx/test/tracing.py b/test/libcxx/test/tracing.py
new file mode 100644
index 000000000000..efef158160c5
--- /dev/null
+++ b/test/libcxx/test/tracing.py
@@ -0,0 +1,34 @@
+import os
+import inspect
+
+
+def trace_function(function, log_calls, log_results, label=''):
+ def wrapper(*args, **kwargs):
+ kwarg_strs = ['{}={}'.format(k, v) for (k, v) in kwargs]
+ arg_str = ', '.join([str(a) for a in args] + kwarg_strs)
+ call_str = '{}({})'.format(function.func_name, arg_str)
+
+ # Perform the call itself, logging before, after, and anything thrown.
+ try:
+ if log_calls:
+ print '{}: Calling {}'.format(label, call_str)
+ res = function(*args, **kwargs)
+ if log_results:
+ print '{}: {} -> {}'.format(label, call_str, res)
+ return res
+ except Exception as ex:
+ if log_results:
+ print '{}: {} raised {}'.format(label, call_str, type(ex))
+ raise ex
+
+ return wrapper
+
+
+def trace_object(obj, log_calls, log_results, label=''):
+ for name, member in inspect.getmembers(obj):
+ if inspect.ismethod(member):
+ # Skip meta-functions, decorate everything else
+ if not member.func_name.startswith('__'):
+ setattr(obj, name, trace_function(member, log_calls,
+ log_results, label))
+ return obj
diff --git a/test/libcxx/type_traits/convert_to_integral.pass.cpp b/test/libcxx/type_traits/convert_to_integral.pass.cpp
new file mode 100644
index 000000000000..b97832b5e6d7
--- /dev/null
+++ b/test/libcxx/type_traits/convert_to_integral.pass.cpp
@@ -0,0 +1,94 @@
+
+// TODO: Make this test pass for all standards.
+// XFAIL: c++98, c++03
+
+#include <limits>
+#include <type_traits>
+#include <cstdint>
+#include <cassert>
+
+#include "user_defined_integral.hpp"
+
+template <class T>
+struct EnumType
+{
+ enum type : T {E_zero, E_one};
+};
+
+
+template <class From, class To>
+void check_integral_types()
+{
+ typedef std::numeric_limits<From> Limits;
+ const From max = Limits::max();
+ const From min = Limits::min();
+ {
+ auto ret = std::__convert_to_integral((From)max);
+ assert(ret == max);
+ ret = std::__convert_to_integral((From)min);
+ assert(ret == min);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+ }
+ {
+ UserDefinedIntegral<From> f(max);
+ auto ret = std::__convert_to_integral(f);
+ assert(ret == max);
+ f.value = min;
+ ret = std::__convert_to_integral(f);
+ assert(ret == min);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+ }
+ {
+ typedef typename EnumType<From>::type Enum;
+ Enum e(static_cast<Enum>(max));
+ auto ret = std::__convert_to_integral(e);
+ assert(ret == max);
+ e = static_cast<Enum>(min);
+ ret = std::__convert_to_integral(min);
+ assert(ret == min);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+ }
+}
+
+
+template <class From, class To>
+void check_enum_types()
+{
+ auto ret = std::__convert_to_integral((From)1);
+ assert(ret == 1);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+}
+
+
+enum enum1 { zero = 0, one = 1 };
+enum enum2 {
+ value = std::numeric_limits<unsigned long>::max()
+};
+
+int main()
+{
+ check_integral_types<bool, int>();
+ check_integral_types<char, int>();
+ check_integral_types<signed char, int>();
+ check_integral_types<unsigned char, int>();
+ check_integral_types<wchar_t, decltype(((wchar_t)1) + 1)>();
+ check_integral_types<char16_t, int>();
+ check_integral_types<char32_t, uint32_t>();
+ check_integral_types<short, int>();
+ check_integral_types<unsigned short, int>();
+ check_integral_types<int, int>();
+ check_integral_types<unsigned, unsigned>();
+ check_integral_types<long, long>();
+ check_integral_types<unsigned long, unsigned long>();
+ check_integral_types<long long, long long>();
+ check_integral_types<unsigned long long, unsigned long long>();
+#ifndef _LIBCPP_HAS_NO_INT128
+ check_integral_types<__int128_t, __int128_t>();
+ check_integral_types<__uint128_t, __uint128_t>();
+#endif
+ // TODO(ericwf): Not standard
+ typedef std::underlying_type<enum1>::type Enum1UT;
+ check_enum_types<enum1, decltype(((Enum1UT)1) + 1)>();
+ typedef std::underlying_type<enum2>::type Enum2UT;
+ check_enum_types<enum2, decltype(((Enum2UT)1) + 1)>();
+}
diff --git a/test/libcxx/util.py b/test/libcxx/util.py
new file mode 100644
index 000000000000..28f2619d69cb
--- /dev/null
+++ b/test/libcxx/util.py
@@ -0,0 +1,46 @@
+from contextlib import contextmanager
+import os
+import tempfile
+
+
+def cleanFile(filename):
+ try:
+ os.remove(filename)
+ except OSError:
+ pass
+
+
+@contextmanager
+def guardedTempFilename(suffix='', prefix='', dir=None):
+ # Creates and yeilds a temporary filename within a with statement. The file
+ # is removed upon scope exit.
+ handle, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir)
+ os.close(handle)
+ yield name
+ cleanFile(name)
+
+
+@contextmanager
+def guardedFilename(name):
+ # yeilds a filename within a with statement. The file is removed upon scope
+ # exit.
+ yield name
+ cleanFile(name)
+
+
+@contextmanager
+def nullContext(value):
+ # yeilds a variable within a with statement. No action is taken upon scope
+ # exit.
+ yield value
+
+
+def makeReport(cmd, out, err, rc):
+ report = "Command: %s\n" % cmd
+ report += "Exit Code: %d\n" % rc
+ if out:
+ report += "Standard Output:\n--\n%s--\n" % out
+ if err:
+ report += "Standard Error:\n--\n%s--\n" % err
+ report += '\n'
+ return report
diff --git a/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
new file mode 100644
index 000000000000..25dd31190685
--- /dev/null
+++ b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//
+// <memory>
+//
+// class shared_ptr
+//
+// This test attempts to create a race condition surrounding use_count()
+// with the hope that TSAN will diagnose it.
+
+#include <memory>
+#include <atomic>
+#include <thread>
+#include <cassert>
+
+typedef std::shared_ptr<int> Ptr;
+typedef std::weak_ptr<int> WeakPtr;
+
+std::atomic_bool Start;
+std::atomic_bool KeepRunning;
+
+struct TestRunner {
+ TestRunner(Ptr xx) : x(xx) {}
+ void operator()() {
+ while (Start == false) {}
+ while (KeepRunning) {
+ // loop to prevent always checking the atomic.
+ for (int i=0; i < 100000; ++i) {
+ Ptr x2 = x; // increment shared count
+ WeakPtr x3 = x; // increment weak count
+ Ptr x4 = x3.lock(); // increment shared count via lock
+ WeakPtr x5 = x3; // increment weak count
+ }
+ }
+ }
+ Ptr x;
+};
+
+void run_test(Ptr p) {
+ Start = false;
+ KeepRunning = true;
+ assert(p.use_count() == 2);
+ TestRunner r(p);
+ assert(p.use_count() == 3);
+ std::thread t1(r); // Start the test thread.
+ assert(p.use_count() == 4);
+ Start = true;
+ // Run until we witness 25 use count changes via both
+ // shared and weak pointer methods.
+ WeakPtr w = p;
+ int shared_changes_count = 0;
+ int weak_changes_count = 0;
+ while (shared_changes_count < 25 && weak_changes_count < 25) {
+ // check use_count on the shared_ptr
+ int last = p.use_count();
+ int new_val = p.use_count();
+ assert(last >= 4);
+ assert(new_val >= 4);
+ if (last != new_val) ++shared_changes_count;
+ // Check use_count on the weak_ptr
+ last = w.use_count();
+ new_val = w.use_count();
+ assert(last >= 4);
+ assert(new_val >= 4);
+ if (last != new_val) ++weak_changes_count;
+ }
+ // kill the test thread.
+ KeepRunning = false;
+ t1.join();
+ assert(p.use_count() == 3);
+}
+
+int main() {
+ {
+ // Test with out-of-place shared_count.
+ Ptr p(new int(42));
+ run_test(p);
+ assert(p.use_count() == 1);
+ }
+ {
+ // Test with in-place shared_count.
+ Ptr p = std::make_shared<int>(42);
+ run_test(p);
+ assert(p.use_count() == 1);
+ }
+}