aboutsummaryrefslogtreecommitdiff
path: root/test/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'test/libcxx')
-rw-r--r--test/libcxx/atomics/libcpp-has-no-threads.fail.cpp23
-rw-r--r--test/libcxx/atomics/libcpp-has-no-threads.pass.cpp18
-rw-r--r--test/libcxx/compiler.py36
-rw-r--r--test/libcxx/containers/sequences/deque/incomplete.pass.cpp31
-rw-r--r--test/libcxx/containers/sequences/vector/asan.pass.cpp71
-rw-r--r--test/libcxx/containers/sequences/vector/asan_throw.pass.cpp233
-rw-r--r--test/libcxx/double_include.sh.cpp7
-rw-r--r--test/libcxx/experimental/any/size_and_alignment.pass.cpp23
-rw-r--r--test/libcxx/experimental/any/small_type.pass.cpp114
-rw-r--r--test/libcxx/experimental/any/version.pass.cpp20
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp44
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp34
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp41
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp1
-rw-r--r--test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp45
-rw-r--r--test/libcxx/test/config.py294
-rw-r--r--test/libcxx/test/format.py21
-rw-r--r--test/libcxx/test/target_info.py223
-rw-r--r--test/libcxx/test/tracing.py6
-rw-r--r--test/libcxx/thread/futures/version.pass.cpp22
-rw-r--r--test/libcxx/type_traits/convert_to_integral.pass.cpp17
-rw-r--r--test/libcxx/type_traits/lazy_metafunctions.pass.cpp137
-rw-r--r--test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp3
-rw-r--r--test/libcxx/utilities/time/date.time/asctime.thread-unsafe.fail.cpp18
-rw-r--r--test/libcxx/utilities/time/date.time/ctime.thread-unsafe.fail.cpp18
-rw-r--r--test/libcxx/utilities/time/date.time/gmtime.thread-unsafe.fail.cpp18
-rw-r--r--test/libcxx/utilities/time/date.time/localtime.thread-unsafe.fail.cpp18
27 files changed, 1242 insertions, 294 deletions
diff --git a/test/libcxx/atomics/libcpp-has-no-threads.fail.cpp b/test/libcxx/atomics/libcpp-has-no-threads.fail.cpp
new file mode 100644
index 000000000000..fe95e6a5983a
--- /dev/null
+++ b/test/libcxx/atomics/libcpp-has-no-threads.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <atomic>
+
+// Test that including <atomic> fails to compile when _LIBCPP_HAS_NO_THREADS
+// is defined.
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+#define _LIBCPP_HAS_NO_THREADS
+#endif
+
+#include <atomic>
+
+int main()
+{
+}
diff --git a/test/libcxx/atomics/libcpp-has-no-threads.pass.cpp b/test/libcxx/atomics/libcpp-has-no-threads.pass.cpp
new file mode 100644
index 000000000000..e587e6b4317a
--- /dev/null
+++ b/test/libcxx/atomics/libcpp-has-no-threads.pass.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-has-no-threads
+
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error This should be XFAIL'd for the purpose of detecting that the LIT feature\
+ 'libcpp-has-no-threads' is available iff _LIBCPP_HAS_NO_THREADS is defined
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/compiler.py b/test/libcxx/compiler.py
index 7afbed461e31..4962038cbbed 100644
--- a/test/libcxx/compiler.py
+++ b/test/libcxx/compiler.py
@@ -150,3 +150,39 @@ class CXXCompiler(object):
cmd, out, err, rc = self.compile(os.devnull, out=os.devnull,
flags=flags)
return rc == 0
+
+ def addCompileFlagIfSupported(self, flag):
+ if isinstance(flag, list):
+ flags = list(flag)
+ else:
+ flags = [flag]
+ if self.hasCompileFlag(flags):
+ self.compile_flags += flags
+ return True
+ else:
+ return False
+
+ def addWarningFlagIfSupported(self, flag):
+ """
+ addWarningFlagIfSupported - Add a warning flag if the compiler
+ supports it. Unlike addCompileFlagIfSupported, this function detects
+ when "-Wno-<warning>" flags are unsupported. If flag is a
+ "-Wno-<warning>" GCC will not emit an unknown option diagnostic unless
+ another error is triggered during compilation.
+ """
+ assert isinstance(flag, str)
+ if not flag.startswith('-Wno-'):
+ return self.addCompileFlagIfSupported(flag)
+ flags = ['-Werror', flag]
+ cmd = self.compileCmd('-', os.devnull, flags)
+ # Remove '-v' because it will cause the command line invocation
+ # to be printed as part of the error output.
+ # TODO(EricWF): Are there other flags we need to worry about?
+ if '-v' in cmd:
+ cmd.remove('-v')
+ out, err, rc = lit.util.executeCommand(cmd, input='#error\n')
+ assert rc != 0
+ if flag in err:
+ return False
+ self.compile_flags += [flag]
+ return True
diff --git a/test/libcxx/containers/sequences/deque/incomplete.pass.cpp b/test/libcxx/containers/sequences/deque/incomplete.pass.cpp
new file mode 100644
index 000000000000..dbeea5f9aefb
--- /dev/null
+++ b/test/libcxx/containers/sequences/deque/incomplete.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// deque()
+// deque::iterator()
+
+#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
+#include <deque>
+#include <cassert>
+
+struct A {
+ std::deque<A> d;
+ std::deque<A>::iterator it;
+ std::deque<A>::reverse_iterator it2;
+};
+
+int main()
+{
+ A a;
+ assert(a.d.size() == 0);
+ a.it = a.d.begin();
+ a.it2 = a.d.rend();
+}
diff --git a/test/libcxx/containers/sequences/vector/asan.pass.cpp b/test/libcxx/containers/sequences/vector/asan.pass.cpp
new file mode 100644
index 000000000000..b102fc08dafb
--- /dev/null
+++ b/test/libcxx/containers/sequences/vector/asan.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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5
+
+// <vector>
+
+// reference operator[](size_type n);
+
+#include <vector>
+#include <cassert>
+#include <cstdlib>
+
+#include "asan_testing.h"
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+#ifndef _LIBCPP_HAS_NO_ASAN
+extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
+
+void do_exit() {
+ exit(0);
+}
+
+int main()
+{
+#if TEST_STD_VER >= 11
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T>> C;
+ const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ C c(std::begin(t), std::end(t));
+ c.reserve(2*c.size());
+ T foo = c[c.size()]; // bad, but not caught by ASAN
+ }
+#endif
+
+ {
+ typedef input_iterator<int*> MyInputIter;
+ // Sould not trigger ASan.
+ std::vector<int> v;
+ v.reserve(1);
+ int i[] = {42};
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1));
+ assert(v[0] == 42);
+ assert(is_contiguous_container_asan_correct(v));
+ }
+
+ __sanitizer_set_death_callback(do_exit);
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ C c(std::begin(t), std::end(t));
+ c.reserve(2*c.size());
+ assert(is_contiguous_container_asan_correct(c));
+ assert(!__sanitizer_verify_contiguous_container ( c.data(), c.data() + 1, c.data() + c.capacity()));
+ T foo = c[c.size()]; // should trigger ASAN
+ assert(false); // if we got here, ASAN didn't trigger
+ }
+}
+#else
+int main () { return 0; }
+#endif
diff --git a/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp b/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
new file mode 100644
index 000000000000..9af3f6be53e8
--- /dev/null
+++ b/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
@@ -0,0 +1,233 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: libcpp-no-exceptions
+// Test asan vector annotations with a class that throws in a CTOR.
+
+#include <vector>
+#include <cassert>
+
+#include "asan_testing.h"
+
+class X {
+public:
+ X(const X &x) { Init(x.a); }
+ X(char arg) { Init(arg); }
+ X() { Init(42); }
+ X &operator=(const X &x) {
+ Init(x.a);
+ return *this;
+ }
+ void Init(char arg) {
+ if (arg == 42)
+ throw 0;
+ if (arg == 66)
+ arg = 42;
+ a = arg;
+ }
+ char get() const { return a; }
+ void set(char arg) { a = arg; }
+
+private:
+ char a;
+};
+
+class ThrowOnCopy {
+public:
+ ThrowOnCopy() : should_throw(false) {}
+ explicit ThrowOnCopy(bool should_throw) : should_throw(should_throw) {}
+
+ ThrowOnCopy(ThrowOnCopy const & other)
+ : should_throw(other.should_throw)
+ {
+ if (should_throw) {
+ throw 0;
+ }
+ }
+
+ bool should_throw;
+};
+
+void test_push_back() {
+ std::vector<X> v;
+ v.reserve(2);
+ v.push_back(X(2));
+ assert(v.size() == 1);
+ try {
+ v.push_back(X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace_back() {
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ std::vector<X> v;
+ v.reserve(2);
+ v.push_back(X(2));
+ assert(v.size() == 1);
+ try {
+ v.emplace_back(42);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
+
+void test_insert_range() {
+ std::vector<X> v;
+ v.reserve(4);
+ v.push_back(X(1));
+ v.push_back(X(2));
+ assert(v.size() == 2);
+ assert(v.capacity() >= 4);
+ try {
+ char a[2] = {21, 42};
+ v.insert(v.end(), a, a + 2);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 3);
+ }
+ assert(v.size() == 3);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_insert() {
+ std::vector<X> v;
+ v.reserve(3);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ try {
+ v.insert(v.end(), X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 2);
+ }
+ assert(v.size() == 2);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace() {
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ std::vector<X> v;
+ v.reserve(3);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ try {
+ v.emplace(v.end(), 42);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 2);
+ }
+ assert(v.size() == 2);
+ assert(is_contiguous_container_asan_correct(v));
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
+
+void test_insert_range2() {
+ std::vector<X> v;
+ v.reserve(4);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ assert(v.capacity() >= 4);
+ try {
+ char a[2] = {10, 42};
+ v.insert(v.begin(), a, a + 2);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() <= 4);
+ assert(is_contiguous_container_asan_correct(v));
+ return;
+ }
+ assert(0);
+}
+
+void test_insert_n() {
+ std::vector<X> v;
+ v.reserve(10);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ try {
+ v.insert(v.begin(), 1, X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() <= 3);
+ assert(is_contiguous_container_asan_correct(v));
+ return;
+ }
+ assert(0);
+}
+
+
+void test_insert_n2() {
+ std::vector<ThrowOnCopy> v(10);
+ v.reserve(100);
+ assert(v.size() == 10);
+ v[6].should_throw = true;
+ try {
+ v.insert(v.cbegin(), 5, ThrowOnCopy());
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 11);
+ assert(is_contiguous_container_asan_correct(v));
+ return;
+ }
+ assert(0);
+}
+
+void test_resize() {
+ std::vector<X> v;
+ v.reserve(3);
+ v.push_back(X(0));
+ try {
+ v.resize(3);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_resize_param() {
+ std::vector<X> v;
+ v.reserve(3);
+ v.push_back(X(0));
+ try {
+ v.resize(3, X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+int main() {
+ test_push_back();
+ test_emplace_back();
+ test_insert_range();
+ test_insert();
+ test_emplace();
+ test_insert_range2();
+ test_insert_n();
+ test_insert_n2();
+ test_resize();
+ test_resize_param();
+}
diff --git a/test/libcxx/double_include.sh.cpp b/test/libcxx/double_include.sh.cpp
index 5620e5b35c2b..99767cf1bbc8 100644
--- a/test/libcxx/double_include.sh.cpp
+++ b/test/libcxx/double_include.sh.cpp
@@ -15,6 +15,12 @@
// RUN: %cxx -o %t.exe %t.first.o %t.second.o %flags %link_flags
// RUN: %run
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+#if defined(__DEPRECATED)
+#undef __DEPRECATED
+#endif
+
#include <algorithm>
#include <array>
#include <bitset>
@@ -50,6 +56,7 @@
#include <deque>
#include <exception>
#include <experimental/algorithm>
+#include <experimental/any>
#include <experimental/chrono>
#include <experimental/dynarray>
#include <experimental/optional>
diff --git a/test/libcxx/experimental/any/size_and_alignment.pass.cpp b/test/libcxx/experimental/any/size_and_alignment.pass.cpp
new file mode 100644
index 000000000000..b7db54020478
--- /dev/null
+++ b/test/libcxx/experimental/any/size_and_alignment.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: c++98, c++03, c++11
+
+// <experimental/any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <experimental/any>
+
+int main()
+{
+ using std::experimental::any;
+ static_assert(sizeof(any) == sizeof(void*)*4, "");
+ static_assert(alignof(any) == alignof(void*), "");
+}
diff --git a/test/libcxx/experimental/any/small_type.pass.cpp b/test/libcxx/experimental/any/small_type.pass.cpp
new file mode 100644
index 000000000000..e6595d4a4ab3
--- /dev/null
+++ b/test/libcxx/experimental/any/small_type.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: c++98, c++03, c++11
+
+// <experimental/any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <experimental/any>
+#include "any_helpers.h"
+
+constexpr std::size_t BufferSize = (sizeof(void*) * 3);
+constexpr std::size_t BufferAlignment = alignof(void*);
+// Clang doesn't like "alignof(BufferAlignment * 2)" due to PR13986.
+// So we create "DoubleBufferAlignment" instead.
+constexpr std::size_t DoubleBufferAlignment = BufferAlignment * 2;
+
+class SmallThrowsDtor
+{
+public:
+ SmallThrowsDtor() {}
+ SmallThrowsDtor(SmallThrowsDtor const &) noexcept {}
+ SmallThrowsDtor(SmallThrowsDtor &&) noexcept {}
+ ~SmallThrowsDtor() noexcept(false) {}
+};
+
+
+struct alignas(1) MaxSizeType {
+ char buff[BufferSize];
+};
+
+struct alignas(BufferAlignment) MaxAlignType {
+};
+
+struct alignas(BufferAlignment) MaxSizeAndAlignType {
+ char buff[BufferSize];
+};
+
+
+struct alignas(1) OverSizeType {
+ char buff[BufferSize + 1];
+};
+
+struct alignas(DoubleBufferAlignment) OverAlignedType {
+};
+
+struct alignas(DoubleBufferAlignment) OverSizeAndAlignedType {
+ char buff[BufferSize + 1];
+};
+
+int main()
+{
+ using std::experimental::any;
+ using std::experimental::__any_imp::_IsSmallObject;
+ static_assert(_IsSmallObject<small>::value, "");
+ static_assert(_IsSmallObject<void*>::value, "");
+ static_assert(!_IsSmallObject<SmallThrowsDtor>::value, "");
+ static_assert(!_IsSmallObject<large>::value, "");
+ {
+ // Check a type that meets the size requirement *exactly* and has
+ // a lesser alignment requirement is considered small.
+ typedef MaxSizeType T;
+ static_assert(sizeof(T) == BufferSize, "");
+ static_assert(alignof(T) < BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the alignment requirement *exactly* and has
+ // a lesser size is considered small.
+ typedef MaxAlignType T;
+ static_assert(sizeof(T) < BufferSize, "");
+ static_assert(alignof(T) == BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the size and alignment requirements *exactly*
+ // is considered small.
+ typedef MaxSizeAndAlignType T;
+ static_assert(sizeof(T) == BufferSize, "");
+ static_assert(alignof(T) == BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the alignment requirements but is over-sized
+ // is not considered small.
+ typedef OverSizeType T;
+ static_assert(sizeof(T) > BufferSize, "");
+ static_assert(alignof(T) < BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the size requirements but is over-aligned
+ // is not considered small.
+ typedef OverAlignedType T;
+ static_assert(sizeof(T) < BufferSize, "");
+ static_assert(alignof(T) > BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that exceeds both the size an alignment requirements
+ // is not considered small.
+ typedef OverSizeAndAlignedType T;
+ static_assert(sizeof(T) > BufferSize, "");
+ static_assert(alignof(T) > BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+}
diff --git a/test/libcxx/experimental/any/version.pass.cpp b/test/libcxx/experimental/any/version.pass.cpp
new file mode 100644
index 000000000000..611d65027b19
--- /dev/null
+++ b/test/libcxx/experimental/any/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/any>
+
+#include <experimental/any>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
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
index 0effac2fc142..738c0c72592e 100644
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-no-exceptions
+// UNSUPPORTED: c++98, c++03, c++11
+
// dynarray.cons
// explicit dynarray(size_type c);
@@ -16,22 +19,21 @@
// ~dynarray();
-
-#include <__config>
-
-#if _LIBCPP_STD_VER > 11
#include <experimental/dynarray>
#include <cassert>
#include <algorithm>
#include <complex>
+#include <limits>
+#include <new>
#include <string>
+
using std::experimental::dynarray;
template <class T>
-void test ( const std::initializer_list<T> &vals ) {
+void testInitList( const std::initializer_list<T> &vals ) {
typedef dynarray<T> dynA;
dynA d1 ( vals );
@@ -41,12 +43,14 @@ void test ( const std::initializer_list<T> &vals ) {
template <class T>
-void test ( const T &val ) {
+void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
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(); } ));
+ if (!DefaultValueIsIndeterminate) {
+ assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
+ }
dynA d2 ( 7, val );
assert ( d2.size () == 7 );
@@ -60,27 +64,23 @@ void test ( const T &val ) {
void test_bad_length () {
try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) + 1 ); }
catch ( std::bad_array_length & ) { return ; }
+ catch (...) { assert(false); }
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<int> ( 14, /* DefaultValueIsIndeterminate */ true ); // ints don't get default initialized
+ test<long> ( 0, true);
+ test<double> ( 14.0, true );
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")} );
+ testInitList( { 1, 1, 2, 3, 5, 8 } );
+ testInitList( { 1., 1., 2., 3., 5., 8. } );
+ testInitList( { 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 );
@@ -88,8 +88,4 @@ int main()
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.cons/default_throws_bad_alloc.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp
new file mode 100644
index 000000000000..612e661ea6db
--- /dev/null
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default_throws_bad_alloc.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: libcpp-no-exceptions
+// dynarray.cons
+
+// explicit dynarray(size_type c);
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// The sanitizers replace new/delete with versions that do not throw bad_alloc.
+// UNSUPPORTED: sanitizer-new-delete, ubsan
+
+
+#include <experimental/dynarray>
+#include <limits>
+#include <new>
+#include <cassert>
+
+
+using std::experimental::dynarray;
+
+int main() {
+ try { dynarray<int>((std::numeric_limits<size_t>::max() / sizeof(int)) - 1); }
+ catch (std::bad_alloc &) { return 0; }
+ catch (...) { assert(false); }
+ assert(false);
+}
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
index b669f25948ed..1bbd8cde92fe 100644
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
@@ -7,15 +7,13 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11
+
// dynarray.data
// T* data() noexcept;
// const T* data() const noexcept;
-
-#include <__config>
-
-#if _LIBCPP_STD_VER > 11
#include <experimental/dynarray>
#include <cassert>
@@ -27,41 +25,44 @@
using std::experimental::dynarray;
template <class T>
-void dyn_test_const ( const dynarray<T> &dyn ) {
+void dyn_test_const(const dynarray<T> &dyn, bool CheckEquals = true) {
const T *data = dyn.data ();
assert ( data != NULL );
- assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+ if (CheckEquals) {
+ assert ( std::equal ( dyn.begin(), dyn.end(), data ));
}
+}
template <class T>
-void dyn_test ( dynarray<T> &dyn ) {
+void dyn_test( dynarray<T> &dyn, bool CheckEquals = true) {
T *data = dyn.data ();
assert ( data != NULL );
- assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+ if (CheckEquals) {
+ assert ( std::equal ( dyn.begin(), dyn.end(), data ));
}
+}
template <class T>
-void test ( const T &val ) {
+void test(const T &val, bool DefaultValueIsIndeterminate = false) {
typedef dynarray<T> dynA;
+
+ const bool CheckDefaultValues = !DefaultValueIsIndeterminate;
+
+ dynA d1(4);
+ dyn_test(d1, CheckDefaultValues);
+ dyn_test_const(d1, CheckDefaultValues);
- dynA d1 ( 4 );
- dyn_test ( d1 );
- dyn_test_const ( d1 );
-
- dynA d2 ( 7, val );
+ dynA d2 (7, val);
dyn_test ( d2 );
dyn_test_const ( d2 );
- }
+}
int main()
{
- test<int> ( 14 );
- test<double> ( 14.0 );
+ test<int>(14, /* DefaultValueIsIndeterminate */ true);
+ test<double>(14.0, true);
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
index 4d77cf732758..8c0d08538716 100644
--- a/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
+++ b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-no-exceptions
// dynarray.overview
// const_reference at(size_type n) const;
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
index e82aa64b98b6..2af862a5530f 100644
--- 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
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11
+
// dynarray.overview
// reference front();
@@ -14,10 +16,6 @@
// reference back();
// const_reference back() const;
-
-#include <__config>
-
-#if _LIBCPP_STD_VER > 11
#include <experimental/dynarray>
#include <cassert>
@@ -29,40 +27,47 @@
using std::experimental::dynarray;
template <class T>
-void dyn_test_const ( const dynarray<T> &dyn ) {
+void dyn_test_const ( const dynarray<T> &dyn, bool CheckValues = true ) {
const T *data = dyn.data ();
- assert ( *data == dyn.front ());
- assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+ assert(data == &dyn.front());
+ assert((data + dyn.size() - 1) == &dyn.back());
+ if (CheckValues) {
+ assert ( *data == dyn.front ());
+ assert ( *(data + dyn.size() - 1 ) == dyn.back ());
}
+}
template <class T>
-void dyn_test ( dynarray<T> &dyn ) {
+void dyn_test ( dynarray<T> &dyn, bool CheckValues = true ) {
T *data = dyn.data ();
- assert ( *data == dyn.front ());
- assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+ assert(data == &dyn.front());
+ assert((data + dyn.size() - 1) == &dyn.back());
+ if (CheckValues) {
+ assert ( *data == dyn.front ());
+ assert ( *(data + dyn.size() - 1 ) == dyn.back ());
}
+}
template <class T>
-void test ( const T &val ) {
+void test ( const T &val, bool DefaultValueIsIndeterminate = false) {
typedef dynarray<T> dynA;
-
+
+ const bool CheckDefaultValues = ! DefaultValueIsIndeterminate;
+
dynA d1 ( 4 );
- dyn_test ( d1 );
- dyn_test_const ( d1 );
+ dyn_test ( d1, CheckDefaultValues );
+ dyn_test_const ( d1, CheckDefaultValues );
dynA d2 ( 7, val );
dyn_test ( d2 );
dyn_test_const ( d2 );
- }
+}
int main()
{
- test<int> ( 14 );
- test<double> ( 14.0 );
+ test<int> ( 14, /* DefaultValueIsIndeterminate */ true);
+ test<double> ( 14.0, true );
test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
test<std::string> ( "fourteen" );
}
-#else
-int main() {}
-#endif
diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py
index 09fbf66dbba0..fefbf01ad450 100644
--- a/test/libcxx/test/config.py
+++ b/test/libcxx/test/config.py
@@ -1,4 +1,3 @@
-import importlib
import locale
import os
import platform
@@ -12,6 +11,7 @@ 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.target_info import make_target_info
from libcxx.test.executor import *
from libcxx.test.tracing import *
@@ -42,13 +42,13 @@ def loadSiteConfig(lit_config, config, param_name, env_name):
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.project_obj_root = None
self.libcxx_src_root = None
self.libcxx_obj_root = None
self.cxx_library_root = None
@@ -141,13 +141,7 @@ class Configuration(object):
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)
+ self.target_info = make_target_info(self)
def configure_cxx(self):
# Gather various compiler parameters.
@@ -179,7 +173,14 @@ class Configuration(object):
'libcxx_src_root', os.path.dirname(self.config.test_source_root))
def configure_obj_root(self):
+ self.project_obj_root = self.get_lit_conf('project_obj_root')
self.libcxx_obj_root = self.get_lit_conf('libcxx_obj_root')
+ if not self.libcxx_obj_root and self.project_obj_root is not None:
+ possible_root = os.path.join(self.project_obj_root, 'projects', 'libcxx')
+ if os.path.isdir(possible_root):
+ self.libcxx_obj_root = possible_root
+ else:
+ self.libcxx_obj_root = self.project_obj_root
def configure_cxx_library_root(self):
self.cxx_library_root = self.get_lit_conf('cxx_library_root',
@@ -211,13 +212,12 @@ class Configuration(object):
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.
+ # default value. Otherwise we ask the target_info.
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'
+ use_lit_shell_default = self.target_info.use_lit_shell_default()
# 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',
@@ -236,63 +236,10 @@ class Configuration(object):
if additional_features:
for f in additional_features.split(','):
self.config.available_features.add(f.strip())
+ self.target_info.add_locale_features(self.config.available_features)
- # 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
@@ -304,17 +251,6 @@ class Configuration(object):
# 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')
@@ -344,38 +280,33 @@ class Configuration(object):
# 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')
+ std = self.get_lit_conf('std')
+ if not std:
+ # Choose the newest possible language dialect if none is given.
+ possible_stds = ['c++1z', 'c++14', 'c++11', 'c++03']
+ for s in possible_stds:
+ if self.cxx.hasCompileFlag('-std=%s' % s):
+ std = s
+ self.lit_config.note(
+ 'inferred language dialect as: %s' % std)
+ break
+ if not std:
+ self.lit_config.fatal(
+ 'Failed to infer a supported language dialect from one of %r'
+ % possible_stds)
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']
+ self.target_info.add_cxx_compile_flags(self.cxx.compile_flags)
# 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()
+ self.configure_compile_flags_abi_version()
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')
@@ -391,6 +322,7 @@ class Configuration(object):
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')]
+ self.configure_config_site_header()
libcxx_headers = self.get_lit_conf(
'libcxx_headers', os.path.join(self.libcxx_src_root, 'include'))
if not os.path.isdir(libcxx_headers):
@@ -398,6 +330,56 @@ class Configuration(object):
% libcxx_headers)
self.cxx.compile_flags += ['-I' + libcxx_headers]
+ def configure_config_site_header(self):
+ # Check for a possible __config_site in the build directory. We
+ # use this if it exists.
+ if self.libcxx_obj_root is None:
+ return
+ config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
+ if not os.path.isfile(config_site_header):
+ return
+ contained_macros = self.parse_config_site_and_add_features(
+ config_site_header)
+ self.lit_config.note('Using __config_site header %s with macros: %r'
+ % (config_site_header, contained_macros))
+ # FIXME: This must come after the call to
+ # 'parse_config_site_and_add_features(...)' in order for it to work.
+ self.cxx.compile_flags += ['-include', config_site_header]
+
+ def parse_config_site_and_add_features(self, header):
+ """ parse_config_site_and_add_features - Deduce and add the test
+ features that that are implied by the #define's in the __config_site
+ header. Return a dictionary containing the macros found in the
+ '__config_site' header.
+ """
+ # Parse the macro contents of __config_site by dumping the macros
+ # using 'c++ -dM -E' and filtering the predefines.
+ predefines = self.cxx.dumpMacros()
+ macros = self.cxx.dumpMacros(header)
+ feature_macros_keys = set(macros.keys()) - set(predefines.keys())
+ feature_macros = {}
+ for k in feature_macros_keys:
+ feature_macros[k] = macros[k]
+ # We expect the header guard to be one of the definitions
+ assert '_LIBCPP_CONFIG_SITE' in feature_macros
+ del feature_macros['_LIBCPP_CONFIG_SITE']
+ # The __config_site header should be non-empty. Otherwise it should
+ # have never been emitted by CMake.
+ assert len(feature_macros) > 0
+ # Transform each macro name into the feature name used in the tests.
+ # Ex. _LIBCPP_HAS_NO_THREADS -> libcpp-has-no-threads
+ for m in feature_macros:
+ if m == '_LIBCPP_ABI_VERSION':
+ self.config.available_features.add('libcpp-abi-version-v%s'
+ % feature_macros[m])
+ continue
+ assert m.startswith('_LIBCPP_HAS_') or m == '_LIBCPP_ABI_UNSTABLE'
+ m = m.lower()[1:].replace('_', '-')
+ self.config.available_features.add(m)
+ return feature_macros
+
+
+
def configure_compile_flags_exceptions(self):
enable_exceptions = self.get_lit_bool('enable_exceptions', True)
if not enable_exceptions:
@@ -410,43 +392,16 @@ class Configuration(object):
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_compile_flags_abi_version(self):
+ abi_version = self.get_lit_conf('abi_version', '').strip()
+ abi_unstable = self.get_lit_bool('abi_unstable')
+ # Only add the ABI version when it is non-default.
+ # FIXME(EricWF): Get the ABI version from the "__config_site".
+ if abi_version and abi_version != '1':
+ self.cxx.compile_flags += ['-D_LIBCPP_ABI_VERSION=' + abi_version]
+ if abi_unstable:
+ self.config.available_features.add('libcpp-abi-unstable')
+ self.cxx.compile_flags += ['-D_LIBCPP_ABI_UNSTABLE']
def configure_link_flags(self):
no_default_flags = self.get_lit_bool('no_default_flags', False)
@@ -505,9 +460,7 @@ class Configuration(object):
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':
+ if self.target_info.allow_cxxabi_link():
self.cxx.link_flags += ['-lc++abi']
elif cxx_abi == 'libcxxrt':
self.cxx.link_flags += ['-lcxxrt']
@@ -518,26 +471,7 @@ class Configuration(object):
'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)
+ self.target_info.add_cxx_link_flags(self.cxx.link_flags)
def configure_color_diagnostics(self):
use_color = self.get_lit_conf('color_diagnostics')
@@ -570,14 +504,28 @@ class Configuration(object):
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']
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER',
+ '-Wall', '-Werror'
+ ]
+ self.cxx.addWarningFlagIfSupported('-Wno-attributes')
+ self.cxx.addWarningFlagIfSupported('-Wno-pessimizing-move')
+ self.cxx.addWarningFlagIfSupported('-Wno-c++11-extensions')
+ self.cxx.addWarningFlagIfSupported('-Wno-user-defined-literals')
+ # TODO(EricWF) Remove the unused warnings once the test suite
+ # compiles clean with them.
+ self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
+ self.cxx.addWarningFlagIfSupported('-Wno-unused-variable')
+ std = self.get_lit_conf('std', None)
+ if std in ['c++98', 'c++03']:
+ # The '#define static_assert' provided by libc++ in C++03 mode
+ # causes an unused local typedef whenever it is used.
+ self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef')
def configure_sanitizer(self):
san = self.get_lit_conf('use_sanitizer', '').strip()
if san:
+ self.target_info.add_sanitizer_features(san, self.config.available_features)
# Search for llvm-symbolizer along the compiler path first
# and then along the PATH env variable.
symbolizer_search_paths = os.environ.get('PATH', '')
@@ -590,8 +538,6 @@ class Configuration(object):
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:
@@ -620,6 +566,10 @@ class Configuration(object):
else:
self.lit_config.fatal('unsupported value for '
'use_sanitizer: {0}'.format(san))
+ san_lib = self.get_lit_conf('sanitizer_library')
+ if san_lib:
+ self.cxx.link_flags += [
+ san_lib, '-Wl,-rpath,%s' % os.path.dirname(san_lib)]
def configure_coverage(self):
self.generate_coverage = self.get_lit_bool('generate_coverage', False)
@@ -692,18 +642,4 @@ class Configuration(object):
"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)
+ self.target_info.configure_env(self.env)
diff --git a/test/libcxx/test/format.py b/test/libcxx/test/format.py
index 238dcdb29af7..19c9fc742a49 100644
--- a/test/libcxx/test/format.py
+++ b/test/libcxx/test/format.py
@@ -64,20 +64,24 @@ class LibcxxTestFormat(object):
return (lit.Test.UNSUPPORTED,
"A lit.local.cfg marked this unsupported")
- res = lit.TestRunner.parseIntegratedTestScript(
+ script = 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 isinstance(script, lit.Test.Result):
+ return script
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)
+ tmpDir, tmpBase = lit.TestRunner.getTempPaths(test)
+ substitutions = lit.TestRunner.getDefaultSubstitutions(test, tmpDir,
+ tmpBase)
+ script = lit.TestRunner.applySubstitutions(script, substitutions)
+
# Dispatch the test based on its suffix.
if is_sh_test:
if not isinstance(self.executor, LocalExecutor):
@@ -86,11 +90,11 @@ class LibcxxTestFormat(object):
return lit.Test.UNSUPPORTED, 'ShTest format not yet supported'
return lit.TestRunner._runShTest(test, lit_config,
self.execute_external, script,
- tmpBase, execDir)
+ tmpBase)
elif is_fail_test:
return self._evaluate_fail_test(test)
elif is_pass_test:
- return self._evaluate_pass_test(test, tmpBase, execDir, lit_config)
+ return self._evaluate_pass_test(test, tmpBase, lit_config)
else:
# No other test type is supported
assert False
@@ -98,7 +102,8 @@ class LibcxxTestFormat(object):
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):
+ def _evaluate_pass_test(self, test, tmpBase, lit_config):
+ execDir = os.path.dirname(test.getExecPath())
source_path = test.getSourcePath()
exec_path = tmpBase + '.exe'
object_path = tmpBase + '.o'
diff --git a/test/libcxx/test/target_info.py b/test/libcxx/test/target_info.py
index a61737786896..667644d2fec6 100644
--- a/test/libcxx/test/target_info.py
+++ b/test/libcxx/test/target_info.py
@@ -1,55 +1,202 @@
+import importlib
+import lit.util # pylint: disable=import-error,no-name-in-module
import locale
+import os
import platform
import sys
-class TargetInfo(object):
+class DefaultTargetInfo(object):
+ def __init__(self, full_config):
+ self.full_config = full_config
+
def platform(self):
- raise NotImplementedError
+ return sys.platform.lower().strip()
- def system(self):
- raise NotImplementedError
+ def add_locale_features(self, features):
+ self.full_config.lit_config.warning(
+ "No locales entry for target_system: %s" % self.platform())
- def platform_ver(self):
- raise NotImplementedError
+ def add_cxx_compile_flags(self, flags): pass
+ def add_cxx_link_flags(self, flags): pass
+ def configure_env(self, env): pass
+ def allow_cxxabi_link(self): return True
+ def add_sanitizer_features(self, sanitizer_type, features): pass
+ def use_lit_shell_default(self): return False
- def platform_name(self):
- raise NotImplementedError
- def supports_locale(self, loc):
- raise NotImplementedError
+def test_locale(loc):
+ assert loc is not None
+ default_locale = locale.setlocale(locale.LC_ALL)
+ try:
+ locale.setlocale(locale.LC_ALL, loc)
+ return True
+ except locale.Error:
+ return False
+ finally:
+ locale.setlocale(locale.LC_ALL, default_locale)
-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 add_common_locales(features, lit_config):
+ # A list of locales needed by the test-suite.
+ # The list uses the canonical name for the locale used in the test-suite
+ # TODO: On Linux ISO8859 *may* needs to hyphenated.
+ locales = [
+ 'en_US.UTF-8',
+ 'fr_FR.UTF-8',
+ 'ru_RU.UTF-8',
+ 'zh_CN.UTF-8',
+ 'fr_CA.ISO8859-1',
+ 'cs_CZ.ISO8859-2'
+ ]
+ for loc in locales:
+ if test_locale(loc):
+ features.add('locale.{0}'.format(loc))
+ else:
+ lit_config.warning('The locale {0} is not supported by '
+ 'your platform. Some tests will be '
+ 'unsupported.'.format(loc))
+
+
+class DarwinLocalTI(DefaultTargetInfo):
+ def __init__(self, full_config):
+ super(DarwinLocalTI, self).__init__(full_config)
+
+ def add_locale_features(self, features):
+ add_common_locales(feature, self.full_config.lit_config)
+
+ def add_cxx_compile_flags(self, flags):
+ try:
+ out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
+ res = 0
+ except OSError:
+ res = -1
+ if res == 0 and out:
+ sdk_path = out
+ self.full_config.lit_config.note('using SDKROOT: %r' % sdk_path)
+ flags += ["-isysroot", sdk_path]
+
+ def add_cxx_link_flags(self, flags):
+ flags += ['-lSystem']
+
+ def configure_env(self, env):
+ library_paths = []
+ # Configure the library path for libc++
+ libcxx_library = self.full_config.get_lit_conf('libcxx_library')
+ if self.full_config.use_system_cxx_lib:
+ pass
+ elif libcxx_library:
+ library_paths += [os.path.dirname(libcxx_library)]
+ elif self.full_config.cxx_library_root:
+ library_paths += [self.full_config.cxx_library_root]
+ # Configure the abi library path
+ if self.full_config.abi_library_root:
+ library_paths += [self.full_config.abi_library_root]
+ if library_paths:
+ env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
+
+ def allow_cxxabi_link(self):
+ # Don't link libc++abi explicitly on OS X because the symbols
+ # should be available in libc++ directly.
+ return False
+
+ def add_sanitizer_features(self, sanitizer_type, features):
+ if san == 'Undefined':
+ features.add('sanitizer-new-delete')
+
+
+class FreeBSDLocalTI(DefaultTargetInfo):
+ def __init__(self, full_config):
+ super(FreeBSDLocalTI, self).__init__(full_config)
- def system(self):
- return platform.system()
+ def add_locale_features(self, features):
+ add_common_locales(features, self.full_config.lit_config)
+
+ def add_cxx_link_flags(self, flags):
+ flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
+
+
+class LinuxLocalTI(DefaultTargetInfo):
+ def __init__(self, full_config):
+ super(LinuxLocalTI, self).__init__(full_config)
+
+ def platform(self):
+ return 'linux'
def platform_name(self):
- if self.platform() == 'linux':
- name, _, _ = platform.linux_distribution()
- name = name.lower().strip()
- if name:
- return name
- return None
+ name, _, _ = platform.linux_distribution()
+ name = name.lower().strip()
+ return name # Permitted to be 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
+ _, ver, _ = platform.linux_distribution()
+ ver = ver.lower().strip()
+ return ver # Permitted to be None.
+
+ def add_locale_features(self, features):
+ add_common_locales(features, self.full_config.lit_config)
+ # 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.
+ name = self.platform_name()
+ ver = self.platform_ver()
+ if name:
+ features.add(name)
+ if name and ver:
+ features.add('%s-%s' % (name, ver))
+
+ def add_cxx_compile_flags(self, flags):
+ flags += ['-D__STDC_FORMAT_MACROS',
+ '-D__STDC_LIMIT_MACROS',
+ '-D__STDC_CONSTANT_MACROS']
+
+ def add_cxx_link_flags(self, flags):
+ enable_threads = ('libcpp-has-no-threads' not in
+ self.full_config.config.available_features)
+ llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
+ flags += ['-lm']
+ if not llvm_unwinder:
+ flags += ['-lgcc_s', '-lgcc']
+ if enable_threads:
+ flags += ['-lpthread']
+ flags += ['-lc']
+ if llvm_unwinder:
+ flags += ['-lunwind', '-ldl']
+ else:
+ flags += ['-lgcc_s', '-lgcc']
+ san = self.full_config.get_lit_conf('use_sanitizer', '').strip()
+ if san:
+ # The libraries and their order are taken from the
+ # linkSanitizerRuntimeDeps function in
+ # clang/lib/Driver/Tools.cpp
+ flags += ['-lpthread', '-lrt', '-lm', '-ldl']
+
+
+class WindowsLocalTI(DefaultTargetInfo):
+ def __init__(self, full_config):
+ super(WindowsLocalTI, self).__init__(full_config)
+
+ def add_locale_features(self, features):
+ add_common_locales(features, self.full_config.lit_config)
+
+ def use_lit_shell_default(self):
+ # Default to the internal shell on Windows, as bash on Windows is
+ # usually very slow.
+ return True
+
+
+def make_target_info(full_config):
+ default = "libcxx.test.target_info.LocalTI"
+ info_str = full_config.get_lit_conf('target_info', default)
+ if info_str != default:
+ mod_path, _, info = info_str.rpartition('.')
+ mod = importlib.import_module(mod_path)
+ target_info = getattr(mod, info)(full_config)
+ full_config.lit_config.note("inferred target_info as: %r" % info_str)
+ return target_info
+ target_system = platform.system()
+ if target_system == 'Darwin': return DarwinLocalTI(full_config)
+ if target_system == 'FreeBSD': return FreeBSDLocalTI(full_config)
+ if target_system == 'Linux': return LinuxLocalTI(full_config)
+ if target_system == 'Windows': return WindowsLocalTI(full_config)
+ return DefaultTargetInfo(full_config)
diff --git a/test/libcxx/test/tracing.py b/test/libcxx/test/tracing.py
index efef158160c5..766fc192f9f5 100644
--- a/test/libcxx/test/tracing.py
+++ b/test/libcxx/test/tracing.py
@@ -11,14 +11,14 @@ def trace_function(function, log_calls, log_results, label=''):
# Perform the call itself, logging before, after, and anything thrown.
try:
if log_calls:
- print '{}: Calling {}'.format(label, call_str)
+ print('{}: Calling {}'.format(label, call_str))
res = function(*args, **kwargs)
if log_results:
- print '{}: {} -> {}'.format(label, call_str, res)
+ print('{}: {} -> {}'.format(label, call_str, res))
return res
except Exception as ex:
if log_results:
- print '{}: {} raised {}'.format(label, call_str, type(ex))
+ print('{}: {} raised {}'.format(label, call_str, type(ex)))
raise ex
return wrapper
diff --git a/test/libcxx/thread/futures/version.pass.cpp b/test/libcxx/thread/futures/version.pass.cpp
new file mode 100644
index 000000000000..6730a1477db7
--- /dev/null
+++ b/test/libcxx/thread/futures/version.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+#include <future>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/libcxx/type_traits/convert_to_integral.pass.cpp b/test/libcxx/type_traits/convert_to_integral.pass.cpp
index b97832b5e6d7..3fdc98f5468f 100644
--- a/test/libcxx/type_traits/convert_to_integral.pass.cpp
+++ b/test/libcxx/type_traits/convert_to_integral.pass.cpp
@@ -1,7 +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.
+//
+//===----------------------------------------------------------------------===//
+//
// TODO: Make this test pass for all standards.
// XFAIL: c++98, c++03
+// <type_traits>
+
+// __convert_to_integral(Tp)
+
+// Test that the __convert_to_integral functions properly converts Tp to the
+// correct type and value for integral, enum and user defined types.
+
#include <limits>
#include <type_traits>
#include <cstdint>
diff --git a/test/libcxx/type_traits/lazy_metafunctions.pass.cpp b/test/libcxx/type_traits/lazy_metafunctions.pass.cpp
new file mode 100644
index 000000000000..8f75080ab956
--- /dev/null
+++ b/test/libcxx/type_traits/lazy_metafunctions.pass.cpp
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: c++98, c++03
+
+// <type_traits>
+
+// __lazy_enable_if, __lazy_not, __lazy_and and __lazy_or
+
+// Test the libc++ lazy meta-programming helpers in <type_traits>
+
+#include <type_traits>
+
+template <class Type>
+struct Identity {
+ typedef Type type;
+};
+
+typedef std::true_type TrueT;
+typedef std::false_type FalseT;
+
+typedef Identity<TrueT> LazyTrueT;
+typedef Identity<FalseT> LazyFalseT;
+
+// A type that cannot be instantiated
+template <class T>
+struct CannotInst {
+ typedef T type;
+ static_assert(std::is_same<T, T>::value == false, "");
+};
+
+
+template <int Value>
+struct NextInt {
+ typedef NextInt<Value + 1> type;
+ static const int value = Value;
+};
+
+template <int Value>
+const int NextInt<Value>::value;
+
+
+template <class Type>
+struct HasTypeImp {
+ template <class Up, class = typename Up::type>
+ static TrueT test(int);
+ template <class>
+ static FalseT test(...);
+
+ typedef decltype(test<Type>(0)) type;
+};
+
+// A metafunction that returns True if Type has a nested 'type' typedef
+// and false otherwise.
+template <class Type>
+struct HasType : HasTypeImp<Type>::type {};
+
+void LazyEnableIfTest() {
+ {
+ typedef std::__lazy_enable_if<true, NextInt<0> > Result;
+ static_assert(HasType<Result>::value, "");
+ static_assert(Result::type::value == 1, "");
+ }
+ {
+ typedef std::__lazy_enable_if<false, CannotInst<int> > Result;
+ static_assert(!HasType<Result>::value, "");
+ }
+}
+
+void LazyNotTest() {
+ {
+ typedef std::__lazy_not<LazyTrueT> NotT;
+ static_assert(std::is_same<typename NotT::type, FalseT>::value, "");
+ static_assert(NotT::value == false, "");
+ }
+ {
+ typedef std::__lazy_not<LazyFalseT> NotT;
+ static_assert(std::is_same<typename NotT::type, TrueT>::value, "");
+ static_assert(NotT::value == true, "");
+ }
+ {
+ // Check that CannotInst<int> is not instantiated.
+ typedef std::__lazy_not<CannotInst<int> > NotT;
+
+ static_assert(std::is_same<NotT, NotT>::value, "");
+
+ }
+}
+
+void LazyAndTest() {
+ { // Test that it acts as the identity function for a single value
+ static_assert(std::__lazy_and<LazyFalseT>::value == false, "");
+ static_assert(std::__lazy_and<LazyTrueT>::value == true, "");
+ }
+ {
+ static_assert(std::__lazy_and<LazyTrueT, LazyTrueT>::value == true, "");
+ static_assert(std::__lazy_and<LazyTrueT, LazyFalseT>::value == false, "");
+ static_assert(std::__lazy_and<LazyFalseT, LazyTrueT>::value == false, "");
+ static_assert(std::__lazy_and<LazyFalseT, LazyFalseT>::value == false, "");
+ }
+ { // Test short circuiting - CannotInst<T> should never be instantiated.
+ static_assert(std::__lazy_and<LazyFalseT, CannotInst<int>>::value == false, "");
+ static_assert(std::__lazy_and<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
+ }
+}
+
+
+void LazyOrTest() {
+ { // Test that it acts as the identity function for a single value
+ static_assert(std::__lazy_or<LazyFalseT>::value == false, "");
+ static_assert(std::__lazy_or<LazyTrueT>::value == true, "");
+ }
+ {
+ static_assert(std::__lazy_or<LazyTrueT, LazyTrueT>::value == true, "");
+ static_assert(std::__lazy_or<LazyTrueT, LazyFalseT>::value == true, "");
+ static_assert(std::__lazy_or<LazyFalseT, LazyTrueT>::value == true, "");
+ static_assert(std::__lazy_or<LazyFalseT, LazyFalseT>::value == false, "");
+ }
+ { // Test short circuiting - CannotInst<T> should never be instantiated.
+ static_assert(std::__lazy_or<LazyTrueT, CannotInst<int>>::value == true, "");
+ static_assert(std::__lazy_or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
+ }
+}
+
+
+int main() {
+ LazyEnableIfTest();
+ LazyNotTest();
+ LazyAndTest();
+ LazyOrTest();
+} \ No newline at end of file
diff --git a/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
index 25dd31190685..fce8443ebd0c 100644
--- a/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
+++ b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
@@ -87,7 +87,8 @@ int main() {
}
{
// Test with in-place shared_count.
- Ptr p = std::make_shared<int>(42);
+ int val = 42;
+ Ptr p = std::make_shared<int>(val);
run_test(p);
assert(p.use_count() == 1);
}
diff --git a/test/libcxx/utilities/time/date.time/asctime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/asctime.thread-unsafe.fail.cpp
new file mode 100644
index 000000000000..3a9749e21c52
--- /dev/null
+++ b/test/libcxx/utilities/time/date.time/asctime.thread-unsafe.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // asctime is not thread-safe.
+ std::time_t t = 0;
+ std::asctime(&t);
+}
diff --git a/test/libcxx/utilities/time/date.time/ctime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/ctime.thread-unsafe.fail.cpp
new file mode 100644
index 000000000000..cd246c631527
--- /dev/null
+++ b/test/libcxx/utilities/time/date.time/ctime.thread-unsafe.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // ctime is not thread-safe.
+ std::time_t t = 0;
+ std::ctime(&t);
+}
diff --git a/test/libcxx/utilities/time/date.time/gmtime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/gmtime.thread-unsafe.fail.cpp
new file mode 100644
index 000000000000..a6debcbd98d8
--- /dev/null
+++ b/test/libcxx/utilities/time/date.time/gmtime.thread-unsafe.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // gmtime is not thread-safe.
+ std::time_t t = 0;
+ std::gmtime(&t);
+}
diff --git a/test/libcxx/utilities/time/date.time/localtime.thread-unsafe.fail.cpp b/test/libcxx/utilities/time/date.time/localtime.thread-unsafe.fail.cpp
new file mode 100644
index 000000000000..c9e55c8fd3a6
--- /dev/null
+++ b/test/libcxx/utilities/time/date.time/localtime.thread-unsafe.fail.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // localtime is not thread-safe.
+ std::time_t t = 0;
+ std::localtime(&t);
+}