aboutsummaryrefslogtreecommitdiff
path: root/test/std
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-29 16:26:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-29 16:26:10 +0000
commitb276b1db48faa7328575ab722fe3bc340623f025 (patch)
tree9e4ba424f754c3f05e409ae647fa358031d97617 /test/std
parentd1bd27794dfbc317e27d1ec63b338115cbf194ba (diff)
Notes
Diffstat (limited to 'test/std')
-rw-r--r--test/std/algorithms/alg.nonmodifying/alg.foreach/for_each_n.pass.cpp61
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.sh.cpp62
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.sh.cpp64
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.sh.cpp73
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.sh.cpp48
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp58
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp57
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp55
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.sh.cpp50
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp67
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp53
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.sh.cpp65
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.sh.cpp84
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.handle/void_handle.sh.cpp55
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.traits/promise_type.sh.cpp81
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp73
-rw-r--r--test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp75
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/await_result.sh.cpp72
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/bool_await_suspend.sh.cpp73
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/expected.sh.cpp93
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/fullexpr-dtor.sh.cpp120
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/generator.sh.cpp107
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/go.sh.cpp182
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/multishot_func.sh.cpp91
-rw-r--r--test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.sh.cpp87
-rw-r--r--test/std/experimental/language.support/support.coroutines/includes.sh.cpp31
-rw-r--r--test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op_astrk/arrow.pass.cpp28
-rw-r--r--test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp1
-rw-r--r--test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp1
-rw-r--r--test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp1
-rw-r--r--test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp3
-rw-r--r--test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp5
-rw-r--r--test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp21
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp13
-rw-r--r--test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp14
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp3
-rw-r--r--test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp3
37 files changed, 1997 insertions, 33 deletions
diff --git a/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each_n.pass.cpp b/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each_n.pass.cpp
new file mode 100644
index 000000000000..fd24edb43060
--- /dev/null
+++ b/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each_n.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// template<class InputIterator, class Size, class Function>
+// InputIterator for_each_n(InputIterator first, Size n, Function f);
+
+
+#include <algorithm>
+#include <cassert>
+
+#include "test_iterators.h"
+
+struct for_each_test
+{
+ for_each_test(int c) : count(c) {}
+ int count;
+ void operator()(int& i) {++i; ++count;}
+};
+
+int main()
+{
+ typedef input_iterator<int*> Iter;
+ int ia[] = {0, 1, 2, 3, 4, 5};
+ const unsigned s = sizeof(ia)/sizeof(ia[0]);
+
+ {
+ auto f = for_each_test(0);
+ Iter it = std::for_each_n(Iter(ia), 0, std::ref(f));
+ assert(it == Iter(ia));
+ assert(f.count == 0);
+ }
+
+ {
+ auto f = for_each_test(0);
+ Iter it = std::for_each_n(Iter(ia), s, std::ref(f));
+
+ assert(it == Iter(ia+s));
+ assert(f.count == s);
+ for (unsigned i = 0; i < s; ++i)
+ assert(ia[i] == static_cast<int>(i+1));
+ }
+
+ {
+ auto f = for_each_test(0);
+ Iter it = std::for_each_n(Iter(ia), 1, std::ref(f));
+
+ assert(it == Iter(ia+1));
+ assert(f.count == 1);
+ for (unsigned i = 0; i < 1; ++i)
+ assert(ia[i] == static_cast<int>(i+2));
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.sh.cpp
new file mode 100644
index 000000000000..a744f56eb811
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.sh.cpp
@@ -0,0 +1,62 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// constexpr explicit operator bool() const noexcept
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test() {
+ static_assert(std::is_nothrow_constructible<bool, C>::value, "");
+ static_assert(!std::is_convertible<C, bool>::value, "");
+ {
+ constexpr C c; ((void)c);
+ static_assert(bool(c) == false, "");
+ }
+ { // null case
+ const C c = {}; ((void)c);
+ ASSERT_NOEXCEPT(bool(c));
+ if (c)
+ assert(false);
+ else
+ assert(true);
+ assert(c.address() == nullptr);
+ assert(bool(c) == false);
+ }
+ { // non-null case
+ char dummy = 42;
+ C c = C::from_address((void*)&dummy);
+ assert(c.address() == &dummy);
+ assert(bool(c) == true);
+ }
+}
+
+int main()
+{
+ do_test<coro::coroutine_handle<>>();
+ do_test<coro::coroutine_handle<int>>();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.sh.cpp
new file mode 100644
index 000000000000..05c3f230e5ca
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.sh.cpp
@@ -0,0 +1,64 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// bool operator==(coroutine_handle<>, coroutine_handle<>) noexcept
+// bool operator!=(coroutine_handle<>, coroutine_handle<>) noexcept
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <utility>
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test(uintptr_t LHSVal, uintptr_t RHSVal) {
+ const C LHS = C::from_address(reinterpret_cast<void*>(LHSVal));
+ const C RHS = C::from_address(reinterpret_cast<void*>(RHSVal));
+ const bool ExpectIsEqual = (LHSVal == RHSVal);
+ assert((LHS == RHS) == ExpectIsEqual);
+ assert((RHS == LHS) == ExpectIsEqual);
+ assert((LHS != RHS) == !ExpectIsEqual);
+ assert((RHS != LHS) == !ExpectIsEqual);
+ {
+ static_assert(noexcept(LHS == RHS), "");
+ static_assert(noexcept(LHS != RHS), "");
+ ASSERT_SAME_TYPE(decltype(LHS == RHS), bool);
+ ASSERT_SAME_TYPE(decltype(LHS != RHS), bool);
+ }
+}
+
+int main()
+{
+ std::pair<uintptr_t, uintptr_t> const TestCases[] = {
+ {0, 0},
+ {16, 16},
+ {0, 16},
+ {16, 0}
+ };
+ for (auto& TC : TestCases) {
+ do_test<coro::coroutine_handle<>>(TC.first, TC.second);
+ do_test<coro::coroutine_handle<int>>(TC.first, TC.second);
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.sh.cpp
new file mode 100644
index 000000000000..7b3bcc394c8c
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.sh.cpp
@@ -0,0 +1,73 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// bool operator<(coroutine_handle<>, coroutine_handle<>) noexcept
+// bool operator>(coroutine_handle<>, coroutine_handle<>) noexcept
+// bool operator>=(coroutine_handle<>, coroutine_handle<>) noexcept
+// bool operator<=(coroutine_handle<>, coroutine_handle<>) noexcept
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <utility>
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test(uintptr_t LHSVal, uintptr_t RHSVal) {
+ const C LHS = C::from_address(reinterpret_cast<void*>(LHSVal));
+ const C RHS = C::from_address(reinterpret_cast<void*>(RHSVal));
+ assert((LHS < RHS) == (LHSVal < RHSVal));
+ assert((RHS < LHS) == (RHSVal < LHSVal));
+ assert((LHS > RHS) == (LHSVal > RHSVal));
+ assert((RHS > LHS) == (RHSVal > LHSVal));
+ assert((LHS <= RHS) == (LHSVal <= RHSVal));
+ assert((RHS <= LHS) == (RHSVal <= LHSVal));
+ assert((LHS >= RHS) == (LHSVal >= RHSVal));
+ assert((RHS >= LHS) == (RHSVal >= LHSVal));
+ {
+ static_assert(noexcept(LHS < RHS), "");
+ static_assert(noexcept(LHS > RHS), "");
+ static_assert(noexcept(LHS <= RHS), "");
+ static_assert(noexcept(LHS >= RHS), "");
+ ASSERT_SAME_TYPE(decltype(LHS < RHS), bool);
+ ASSERT_SAME_TYPE(decltype(LHS > RHS), bool);
+ ASSERT_SAME_TYPE(decltype(LHS <= RHS), bool);
+ ASSERT_SAME_TYPE(decltype(LHS >= RHS), bool);
+ }
+}
+
+int main()
+{
+ std::pair<uintptr_t, uintptr_t> const TestCases[] = {
+ {0, 0},
+ {16, 16},
+ {0, 16},
+ {16, 0}
+ };
+ for (auto& TC : TestCases) {
+ do_test<coro::coroutine_handle<>>(TC.first, TC.second);
+ do_test<coro::coroutine_handle<int>>(TC.first, TC.second);
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.sh.cpp
new file mode 100644
index 000000000000..48c3ca50cbf1
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.sh.cpp
@@ -0,0 +1,48 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// bool done() const
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <memory>
+#include <utility>
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class Promise>
+void do_test(coro::coroutine_handle<Promise> const& H) {
+ // FIXME Add a runtime test
+ {
+ ASSERT_SAME_TYPE(decltype(H.done()), bool);
+ ASSERT_NOT_NOEXCEPT(H.done());
+ }
+}
+
+int main()
+{
+ do_test(coro::coroutine_handle<>{});
+ do_test(coro::coroutine_handle<int>{});
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp
new file mode 100644
index 000000000000..9e7fb5b2f687
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp
@@ -0,0 +1,58 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// coroutine_handle& operator=(nullptr_t) noexcept
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <cassert>
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test() {
+ int dummy = 42;
+ void* dummy_h = &dummy;
+ {
+ C c; ((void)c);
+ static_assert(std::is_nothrow_assignable<C&, std::nullptr_t>::value, "");
+ static_assert(!std::is_assignable<C&, void*>::value, "");
+ }
+ {
+ C c = C::from_address(dummy_h);
+ assert(c.address() == &dummy);
+ c = nullptr;
+ assert(c.address() == nullptr);
+ c = nullptr;
+ assert(c.address() == nullptr);
+ }
+ {
+ C c;
+ C& cr = (c = nullptr);
+ assert(&c == &cr);
+ }
+}
+
+int main()
+{
+ do_test<coro::coroutine_handle<>>();
+ do_test<coro::coroutine_handle<int>>();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp
new file mode 100644
index 000000000000..961253fb7ca5
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp
@@ -0,0 +1,57 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// constexpr coroutine_handle() noexcept
+// constexpr coroutine_handle(nullptr_t) noexcept
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <cassert>
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test() {
+ {
+ constexpr C c;
+ static_assert(std::is_nothrow_default_constructible<C>::value, "");
+ static_assert(c.address() == nullptr, "");
+ }
+ {
+ constexpr C c(nullptr);
+ static_assert(std::is_nothrow_constructible<C, std::nullptr_t>::value, "");
+ static_assert(c.address() == nullptr, "");
+ }
+ {
+ C c;
+ assert(c.address() == nullptr);
+ }
+ {
+ C c(nullptr);
+ assert(c.address() == nullptr);
+ }
+}
+
+int main()
+{
+ do_test<coro::coroutine_handle<>>();
+ do_test<coro::coroutine_handle<int>>();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp
new file mode 100644
index 000000000000..7258f93905f3
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp
@@ -0,0 +1,55 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// constexpr void* address() const noexcept
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test() {
+ {
+ constexpr C c; ((void)c);
+ static_assert(c.address() == nullptr, "");
+ }
+ {
+ const C c = {}; ((void)c);
+ ASSERT_NOEXCEPT(c.address());
+ ASSERT_SAME_TYPE(decltype(c.address()), void*);
+ assert(c.address() == nullptr);
+ }
+ {
+ char dummy = 42;
+ C c = C::from_address((void*)&dummy);
+ assert(c.address() == &dummy);
+ }
+}
+
+int main()
+{
+ do_test<coro::coroutine_handle<>>();
+ do_test<coro::coroutine_handle<int>>();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.sh.cpp
new file mode 100644
index 000000000000..26a45b033ff5
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.sh.cpp
@@ -0,0 +1,50 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// static coroutine_handle from_address(void*) noexcept
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <cassert>
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test() {
+ {
+ C c = C::from_address(nullptr);
+ static_assert(noexcept(C::from_address(nullptr)), "");
+ // FIXME: Should the return type not be 'C'?
+ static_assert(std::is_same<decltype(C::from_address(nullptr)), C>::value, "");
+ assert(c.address() == nullptr);
+ }
+ {
+ char dummy = 42;
+ C c = C::from_address((void*)&dummy);
+ assert(c.address() == &dummy);
+ }
+}
+
+int main()
+{
+ do_test<coro::coroutine_handle<>>();
+ do_test<coro::coroutine_handle<int>>();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp
new file mode 100644
index 000000000000..5f66b3e11314
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp
@@ -0,0 +1,67 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// namespace std {
+// template <class P> struct hash<experimental::coroutine_handle<P>>;
+// }
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <memory>
+#include <utility>
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class C>
+void do_test(uintptr_t LHSVal, uintptr_t RHSVal) {
+ const size_t ExpectLHS = std::hash<void*>{}(reinterpret_cast<void*>(LHSVal));
+ const size_t ExpectRHS = std::hash<void*>{}(reinterpret_cast<void*>(RHSVal));
+ const C LHS = C::from_address(reinterpret_cast<void*>(LHSVal));
+ const C RHS = C::from_address(reinterpret_cast<void*>(RHSVal));
+ const std::hash<C> h;
+ // FIXME: libc++'s implementation hash's the result of LHS.address(), so we
+ // expect that value. However this is not required.
+ assert(h(LHS) == ExpectLHS);
+ assert(h(RHS) == ExpectRHS);
+ assert((h(LHS) == h(RHS)) == (LHSVal == RHSVal));
+ {
+ ASSERT_SAME_TYPE(decltype(h(LHS)), size_t);
+ ASSERT_NOEXCEPT(std::hash<C>{}(LHS));
+ }
+}
+
+int main()
+{
+ std::pair<uintptr_t, uintptr_t> const TestCases[] = {
+ {0, 0},
+ {0, 8},
+ {8, 8},
+ {8, 16}
+ };
+ for (auto& TC : TestCases) {
+ do_test<coro::coroutine_handle<>>(TC.first, TC.second);
+ do_test<coro::coroutine_handle<int>>(TC.first, TC.second);
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp
new file mode 100644
index 000000000000..b38d7871be4b
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp
@@ -0,0 +1,53 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise>
+// struct coroutine_handle<Promise>;
+
+// Promise& promise() const
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <memory>
+#include <utility>
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class Promise>
+void do_test(coro::coroutine_handle<Promise>&& H) {
+
+ // FIXME Add a runtime test
+ {
+ ASSERT_SAME_TYPE(decltype(H.promise()), Promise&);
+ LIBCPP_ASSERT_NOT_NOEXCEPT(H.promise());
+ }
+ {
+ auto const& CH = H;
+ ASSERT_SAME_TYPE(decltype(CH.promise()), Promise&);
+ LIBCPP_ASSERT_NOT_NOEXCEPT(CH.promise());
+ }
+}
+
+int main()
+{
+ do_test(coro::coroutine_handle<int>{});
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.sh.cpp
new file mode 100644
index 000000000000..9cc0d1d72bf7
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.sh.cpp
@@ -0,0 +1,65 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// void destroy()
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <memory>
+#include <utility>
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+template <class H>
+auto has_destroy_imp(H&& h, int) -> decltype(h.destroy(), std::true_type{});
+template <class H>
+auto has_destroy_imp(H&&, long) -> std::false_type;
+
+template <class H>
+constexpr bool has_destroy() {
+ return decltype(has_destroy_imp(std::declval<H>(), 0))::value;
+}
+
+template <class Promise>
+void do_test(coro::coroutine_handle<Promise>&& H) {
+ using HType = coro::coroutine_handle<Promise>;
+ // FIXME Add a runtime test
+ {
+ ASSERT_SAME_TYPE(decltype(H.destroy()), void);
+ LIBCPP_ASSERT_NOT_NOEXCEPT(H.destroy());
+ static_assert(has_destroy<HType&>(), "");
+ static_assert(has_destroy<HType&&>(), "");
+ }
+ {
+ static_assert(!has_destroy<HType const&>(), "");
+ static_assert(!has_destroy<HType const&&>(), "");
+ }
+}
+
+int main()
+{
+ do_test(coro::coroutine_handle<>{});
+ do_test(coro::coroutine_handle<int>{});
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.sh.cpp
new file mode 100644
index 000000000000..b5ff187a49ce
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.sh.cpp
@@ -0,0 +1,84 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// template <class Promise = void>
+// struct coroutine_handle;
+
+// void operator()()
+// void resume()
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <memory>
+#include <utility>
+#include <cstdint>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+
+template <class H>
+auto has_resume_imp(H&& h, int) -> decltype(h.resume(), std::true_type{});
+template <class H>
+auto has_resume_imp(H&&, long) -> std::false_type;
+
+template <class H>
+constexpr bool has_resume() {
+ return decltype(has_resume_imp(std::declval<H>(), 0))::value;
+}
+
+
+template <class H>
+auto has_call_operator_imp(H&& h, int) -> decltype(h(), std::true_type{});
+template <class H>
+auto has_call_operator_imp(H&&, long) -> std::false_type;
+
+template <class H>
+constexpr bool has_call_operator() {
+ return decltype(has_call_operator_imp(std::declval<H>(), 0))::value;
+}
+
+template <class Promise>
+void do_test(coro::coroutine_handle<Promise>&& H) {
+ using HType = coro::coroutine_handle<Promise>;
+ // FIXME Add a runtime test
+ {
+ ASSERT_SAME_TYPE(decltype(H.resume()), void);
+ ASSERT_SAME_TYPE(decltype(H()), void);
+ LIBCPP_ASSERT_NOT_NOEXCEPT(H.resume());
+ LIBCPP_ASSERT_NOT_NOEXCEPT(H());
+ static_assert(has_resume<HType&>(), "");
+ static_assert(has_resume<HType&&>(), "");
+ static_assert(has_call_operator<HType&>(), "");
+ static_assert(has_call_operator<HType&&>(), "");
+ }
+ {
+ static_assert(!has_resume<HType const&>(), "");
+ static_assert(!has_resume<HType const&&>(), "");
+ static_assert(!has_call_operator<HType const&>(), "");
+ static_assert(!has_call_operator<HType const&&>(), "");
+ }
+}
+
+int main()
+{
+ do_test(coro::coroutine_handle<>{});
+ do_test(coro::coroutine_handle<int>{});
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.handle/void_handle.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.handle/void_handle.sh.cpp
new file mode 100644
index 000000000000..945304a4673d
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.handle/void_handle.sh.cpp
@@ -0,0 +1,55 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+
+namespace coro = std::experimental;
+
+struct A {
+ using promise_type = A*;
+};
+
+struct B {};
+struct C {};
+
+namespace std { namespace experimental {
+ template <>
+ struct coroutine_traits<::A, int> {
+ using promise_type = int*;
+ };
+ template <class ...Args>
+ struct coroutine_traits<::B, Args...> {
+ using promise_type = B*;
+ };
+ template <>
+ struct coroutine_traits<::C> {
+ using promise_type = void;
+ };
+}}
+
+template <class Expect, class T, class ...Args>
+void check_type() {
+ using P = typename coro::coroutine_traits<T, Args...>::promise_type ;
+ static_assert(std::is_same<P, Expect>::value, "");
+};
+
+int main()
+{
+ check_type<A*, A>();
+ check_type<int*, A, int>();
+ check_type<B*, B>();
+ check_type<void, C>();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.traits/promise_type.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.traits/promise_type.sh.cpp
new file mode 100644
index 000000000000..c1d3b818d403
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.traits/promise_type.sh.cpp
@@ -0,0 +1,81 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+
+namespace coro = std::experimental;
+
+template <class T, class = typename T::promise_type>
+constexpr bool has_promise_type(int) { return true; }
+template <class>
+constexpr bool has_promise_type(long) { return false; }
+template <class T>
+constexpr bool has_promise_type() { return has_promise_type<T>(0); }
+
+struct A {
+ using promise_type = A*;
+};
+
+struct B {};
+struct C {};
+struct D {
+private:
+ using promise_type = void;
+};
+struct E {};
+
+namespace std { namespace experimental {
+ template <>
+ struct coroutine_traits<::A, int> {
+ using promise_type = int*;
+ };
+ template <class ...Args>
+ struct coroutine_traits<::B, Args...> {
+ using promise_type = B*;
+ };
+ template <>
+ struct coroutine_traits<::C> {
+ using promise_type = void;
+ };
+}}
+
+template <class Expect, class T, class ...Args>
+void check_type() {
+ using Traits = coro::coroutine_traits<T, Args...>;
+ static_assert(has_promise_type<Traits>(), "");
+ static_assert(std::is_same<typename Traits::promise_type, Expect>::value, "");
+}
+
+template <class T, class ...Args>
+void check_no_type() {
+ using Traits = coro::coroutine_traits<T, Args...>;
+ static_assert(!has_promise_type<Traits>(), "");
+}
+
+int main()
+{
+ {
+ check_type<A*, A>();
+ check_type<int*, A, int>();
+ check_type<B*, B>();
+ check_type<void, C>();
+ }
+ {
+ check_no_type<D>();
+ check_no_type<E>();
+ check_no_type<C, int>();
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp
new file mode 100644
index 000000000000..1987f68e70ab
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp
@@ -0,0 +1,73 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+using SuspendT = std::experimental::coroutines_v1::suspend_always;
+
+TEST_SAFE_STATIC SuspendT safe_sa;
+constexpr SuspendT constexpr_sa;
+
+constexpr bool check_suspend_constexpr() {
+ SuspendT s{};
+ const SuspendT scopy(s); ((void)scopy);
+ SuspendT smove(std::move(s)); ((void)smove);
+ s = scopy;
+ s = std::move(smove);
+ return true;
+}
+
+int main()
+{
+ using H = coro::coroutine_handle<>;
+ using S = SuspendT;
+ H h{};
+ S s{};
+ S const& cs = s;
+ {
+ LIBCPP_STATIC_ASSERT(noexcept(s.await_ready()), "");
+ static_assert(std::is_same<decltype(s.await_ready()), bool>::value, "");
+ assert(s.await_ready() == false);
+ assert(cs.await_ready() == false);
+ }
+ {
+ LIBCPP_STATIC_ASSERT(noexcept(s.await_suspend(h)), "");
+ static_assert(std::is_same<decltype(s.await_suspend(h)), void>::value, "");
+ s.await_suspend(h);
+ cs.await_suspend(h);
+ }
+ {
+ LIBCPP_STATIC_ASSERT(noexcept(s.await_resume()), "");
+ static_assert(std::is_same<decltype(s.await_resume()), void>::value, "");
+ s.await_resume();
+ cs.await_resume();
+ }
+ {
+ static_assert(std::is_nothrow_default_constructible<S>::value, "");
+ static_assert(std::is_nothrow_copy_constructible<S>::value, "");
+ static_assert(std::is_nothrow_move_constructible<S>::value, "");
+ static_assert(std::is_nothrow_copy_assignable<S>::value, "");
+ static_assert(std::is_nothrow_move_assignable<S>::value, "");
+ static_assert(std::is_trivially_copyable<S>::value, "");
+ static_assert(check_suspend_constexpr(), "");
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp b/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp
new file mode 100644
index 000000000000..72e0ac024558
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp
@@ -0,0 +1,75 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace coro = std::experimental;
+
+// Test that the type is in the correct namespace
+using SuspendT = std::experimental::coroutines_v1::suspend_never;
+
+TEST_SAFE_STATIC SuspendT safe_sn;
+constexpr SuspendT constexpr_sn;
+
+constexpr bool check_suspend_constexpr() {
+ SuspendT s{};
+ const SuspendT scopy(s); ((void)scopy);
+ SuspendT smove(std::move(s)); ((void)smove);
+ s = scopy;
+ s = std::move(smove);
+ return true;
+}
+
+
+int main()
+{
+ using H = coro::coroutine_handle<>;
+ using S = SuspendT;
+ H h{};
+ S s{};
+ S const& cs = s;
+ {
+ LIBCPP_STATIC_ASSERT(noexcept(s.await_ready()), "");
+ static_assert(std::is_same<decltype(s.await_ready()), bool>::value, "");
+ assert(s.await_ready() == true);
+ assert(cs.await_ready() == true);
+ }
+ {
+ LIBCPP_STATIC_ASSERT(noexcept(s.await_suspend(h)), "");
+ static_assert(std::is_same<decltype(s.await_suspend(h)), void>::value, "");
+ s.await_suspend(h);
+ cs.await_suspend(h);
+ }
+ {
+ LIBCPP_STATIC_ASSERT(noexcept(s.await_resume()), "");
+ static_assert(std::is_same<decltype(s.await_resume()), void>::value, "");
+ s.await_resume();
+ cs.await_resume();
+ }
+ {
+ static_assert(std::is_nothrow_default_constructible<S>::value, "");
+ static_assert(std::is_nothrow_copy_constructible<S>::value, "");
+ static_assert(std::is_nothrow_move_constructible<S>::value, "");
+ static_assert(std::is_nothrow_copy_assignable<S>::value, "");
+ static_assert(std::is_nothrow_move_assignable<S>::value, "");
+ static_assert(std::is_trivially_copyable<S>::value, "");
+ static_assert(check_suspend_constexpr(), "");
+ }
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/await_result.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/await_result.sh.cpp
new file mode 100644
index 000000000000..cca875d1a6ba
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/await_result.sh.cpp
@@ -0,0 +1,72 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <cassert>
+
+using namespace std::experimental;
+
+struct coro_t {
+ struct promise_type {
+ coro_t get_return_object() {
+ coroutine_handle<promise_type>{};
+ return {};
+ }
+ suspend_never initial_suspend() { return {}; }
+ suspend_never final_suspend() { return {}; }
+ void return_void(){}
+ static void unhandled_exception() {}
+ };
+};
+
+struct B {
+ ~B() {}
+ bool await_ready() { return true; }
+ B await_resume() { return {}; }
+ template <typename F> void await_suspend(F) {}
+};
+
+
+struct A {
+ ~A(){}
+ bool await_ready() { return true; }
+ int await_resume() { return 42; }
+ template <typename F> void await_suspend(F) {}
+};
+
+int last_value = -1;
+void set_value(int x) {
+ last_value = x;
+}
+
+coro_t f(int n) {
+ if (n == 0) {
+ set_value(0);
+ co_return;
+ }
+ int val = co_await A{};
+ set_value(42);
+}
+
+coro_t g() { B val = co_await B{}; }
+
+int main() {
+ last_value = -1;
+ f(0);
+ assert(last_value == 0);
+ f(1);
+ assert(last_value == 42);
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/bool_await_suspend.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/bool_await_suspend.sh.cpp
new file mode 100644
index 000000000000..e51ac67f0fef
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/bool_await_suspend.sh.cpp
@@ -0,0 +1,73 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// FIXME: When run under UBSAN this test hits an assertion inside Clang
+// XFAIL: ubsan
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <cassert>
+
+using namespace std::experimental;
+
+struct coro_t {
+ struct promise_type {
+ coro_t get_return_object() {
+ return coroutine_handle<promise_type>::from_promise(*this);
+ }
+ suspend_never initial_suspend() { return {}; }
+ suspend_never final_suspend() { return {}; }
+ void return_void(){}
+ void unhandled_exception() {}
+ };
+ coro_t(coroutine_handle<promise_type> hh) : h(hh) {}
+ coroutine_handle<promise_type> h;
+};
+
+struct NoSuspend {
+ bool await_ready() { return false; }
+ void await_resume() {}
+ template <typename F> bool await_suspend(F) { return false; }
+};
+
+struct DoSuspend {
+ bool await_ready() { return false; }
+ void await_resume() {}
+ template <typename F> bool await_suspend(F) { return true; }
+};
+
+bool f_started, f_resumed = false;
+coro_t f() {
+ f_started = true;
+ co_await DoSuspend{};
+ f_resumed = true;
+}
+
+bool g_started, g_resumed = false;
+coro_t g() {
+ g_started = true;
+ co_await NoSuspend{};
+ g_resumed = true;
+}
+
+int main() {
+ assert(!f_started && !f_resumed && !g_started && !g_resumed);
+ auto fret = f();
+ assert(f_started && !f_resumed);
+ fret.h.destroy();
+ assert(f_started && !f_resumed);
+ g();
+ assert(g_started && g_resumed);
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/expected.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/expected.sh.cpp
new file mode 100644
index 000000000000..b6832b0c1886
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/expected.sh.cpp
@@ -0,0 +1,93 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <cassert>
+using namespace std::experimental;
+
+struct error {};
+
+template <typename T, typename Error = int>
+struct expected {
+
+ struct Data {
+ T val;
+ Error error;
+ };
+ Data data;
+
+ struct DataPtr {
+ Data *p;
+ ~DataPtr() { delete p; }
+ };
+
+ expected() {}
+ expected(T val) : data{std::move(val),{}} {}
+ expected(struct error, Error error) : data{{}, std::move(error)} {}
+ expected(DataPtr & p) : data{std::move(p.p->val), std::move(p.p->error)} {}
+
+ struct promise_type {
+ Data* data;
+ DataPtr get_return_object() { data = new Data{}; return {data}; }
+ suspend_never initial_suspend() { return {}; }
+ suspend_never final_suspend() { return {}; }
+ void return_value(T v) { data->val = std::move(v); data->error = {};}
+ void unhandled_exception() {}
+ };
+
+ bool await_ready() { return !data.error; }
+ T await_resume() { return std::move(data.val); }
+ void await_suspend(coroutine_handle<promise_type> h) {
+ h.promise().data->error =std::move(data.error);
+ h.destroy();
+ }
+
+ T const& value() { return data.val; }
+ Error const& error() { return data.error; }
+};
+
+expected<int> g() { return {0}; }
+expected<int> h() { return {error{}, 42}; }
+
+extern "C" void print(int);
+
+bool f1_started, f1_resumed = false;
+expected<int> f1() {
+ f1_started = true;
+ (void)(co_await g());
+ f1_resumed = true;
+ co_return 100;
+}
+
+bool f2_started, f2_resumed = false;
+expected<int> f2() {
+ f2_started = true;
+ (void)(co_await h());
+ f2_resumed = true;
+ co_return 200;
+}
+
+int main() {
+ auto c1 = f1();
+ assert(f1_started && f1_resumed);
+ assert(c1.value() == 100);
+ assert(c1.error() == 0);
+
+ auto c2 = f2();
+ assert(f2_started && !f2_resumed);
+ assert(c2.value() == 0);
+ assert(c2.error() == 42);
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/fullexpr-dtor.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/fullexpr-dtor.sh.cpp
new file mode 100644
index 000000000000..c7e34fe919e1
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/fullexpr-dtor.sh.cpp
@@ -0,0 +1,120 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <cassert>
+
+#include "test_macros.h"
+
+using namespace std::experimental;
+
+int alive = 0;
+int ctor_called = 0;
+int dtor_called = 0;
+void reset() {
+ assert(alive == 0);
+ alive = 0;
+ ctor_called = 0;
+ dtor_called = 0;
+}
+struct Noisy {
+ Noisy() { ++alive; ++ctor_called; }
+ ~Noisy() { --alive; ++dtor_called; }
+#if TEST_STD_VER > 14
+ Noisy(Noisy const&) = delete;
+#else
+ // FIXME: This test depends on copy elision taking place in C++14
+ // (pre-c++17 guaranteed copy elision)
+ Noisy(Noisy const&);
+#endif
+};
+
+struct Bug {
+ bool await_ready() { return true; }
+ void await_suspend(std::experimental::coroutine_handle<>) {}
+ Noisy await_resume() { return {}; }
+};
+struct coro2 {
+ struct promise_type {
+ suspend_never initial_suspend() { return{}; }
+ suspend_never final_suspend() { return{}; }
+ coro2 get_return_object() { return{}; }
+ void return_void() {}
+ Bug yield_value(int) { return {}; }
+ void unhandled_exception() {}
+ };
+};
+
+// Checks that destructors are correctly invoked for the object returned by
+// coawait.
+coro2 a() {
+ reset();
+ {
+ auto x = co_await Bug{};
+ assert(alive == 1);
+ assert(ctor_called == 1);
+ assert(dtor_called == 0);
+ }
+ assert(alive == 0);
+ assert(dtor_called == 1);
+}
+
+coro2 b() {
+ reset();
+ {
+ co_await Bug{};
+ assert(ctor_called == 1);
+ assert(dtor_called == 1);
+ assert(alive == 0);
+ }
+ assert(ctor_called == 1);
+ assert(dtor_called == 1);
+ assert(alive == 0);
+
+}
+
+coro2 c() {
+ reset();
+ {
+ auto x = co_yield 42;
+ assert(alive == 1);
+ assert(ctor_called == 1);
+ assert(dtor_called == 0);
+ }
+ assert(alive == 0);
+ assert(ctor_called == 1);
+ assert(dtor_called == 1);
+}
+
+coro2 d() {
+ reset();
+ {
+ co_yield 42;
+ assert(ctor_called == 1);
+ assert(dtor_called == 1);
+ assert(alive == 0);
+ }
+ assert(alive == 0);
+ assert(ctor_called == 1);
+ assert(dtor_called == 1);
+}
+
+int main() {
+ a();
+ b();
+ c();
+ d();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/generator.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/generator.sh.cpp
new file mode 100644
index 000000000000..4681793ed814
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/generator.sh.cpp
@@ -0,0 +1,107 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// FIXME: When run under UBSAN this test hits an assertion inside Clang
+// XFAIL: ubsan
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <vector>
+#include <cassert>
+
+#include "coroutine_types.h"
+
+using namespace std::experimental;
+
+struct minig {
+ struct promise_type {
+ int current_value;
+ suspend_always yield_value(int value) {
+ this->current_value = value;
+ return {};
+ }
+ suspend_always initial_suspend() { return {}; }
+ suspend_always final_suspend() { return {}; }
+ minig get_return_object() { return minig{this}; };
+ void return_void() {}
+ void unhandled_exception() {}
+ };
+
+ bool move_next() {
+ p.resume();
+ return !p.done();
+ }
+ int current_value() { return p.promise().current_value; }
+
+ minig(minig &&rhs) : p(rhs.p) { rhs.p = nullptr; }
+
+ ~minig() {
+ if (p)
+ p.destroy();
+ }
+
+private:
+ explicit minig(promise_type *p)
+ : p(coroutine_handle<promise_type>::from_promise(*p)) {}
+
+ coroutine_handle<promise_type> p;
+};
+
+
+minig mini_count(int n) {
+ for (int i = 0; i < n; i++) {
+ co_yield i;
+ }
+}
+
+generator<int> count(int n) {
+ for (int i = 0; i < n; ++i)
+ co_yield i;
+}
+
+generator<int> range(int from, int n) {
+ for (int i = from; i < n; ++i)
+ co_yield i;
+}
+
+void test_count() {
+ const std::vector<int> expect = {0, 1, 2, 3, 4};
+ std::vector<int> got;
+ for (auto x : count(5))
+ got.push_back(x);
+ assert(expect == got);
+}
+
+void test_range() {
+ int sum = 0;
+ for (auto v: range(1, 20))
+ sum += v;
+ assert(sum == 190);
+}
+
+void test_mini_generator() {
+ int sum = 0;
+ auto g = mini_count(5);
+ while (g.move_next()) {
+ sum += g.current_value();
+ }
+ assert(sum == 10);
+}
+
+int main() {
+ test_count();
+ test_range();
+ test_mini_generator();
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/go.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/go.sh.cpp
new file mode 100644
index 000000000000..e0d69104fdaf
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/go.sh.cpp
@@ -0,0 +1,182 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <cassert>
+
+using namespace std::experimental;
+
+bool cancel = false;
+
+struct goroutine
+{
+ static int const N = 10;
+ static int count;
+ static coroutine_handle<> stack[N];
+
+ static void schedule(coroutine_handle<>& rh)
+ {
+ assert(count < N);
+ stack[count++] = rh;
+ rh = nullptr;
+ }
+
+ ~goroutine() {}
+
+ static void go(goroutine) {}
+
+ static void run_one()
+ {
+ assert(count > 0);
+ stack[--count]();
+ }
+
+ struct promise_type
+ {
+ suspend_never initial_suspend() {
+ return {};
+ }
+ suspend_never final_suspend() {
+ return {};
+ }
+ void return_void() {}
+ goroutine get_return_object() {
+ return{};
+ }
+ void unhandled_exception() {}
+ };
+};
+int goroutine::count;
+coroutine_handle<> goroutine::stack[N];
+
+coroutine_handle<goroutine::promise_type> workaround;
+
+class channel;
+
+struct push_awaiter {
+ channel* ch;
+ bool await_ready() {return false; }
+ void await_suspend(coroutine_handle<> rh);
+ void await_resume() {}
+};
+
+struct pull_awaiter {
+ channel * ch;
+
+ bool await_ready();
+ void await_suspend(coroutine_handle<> rh);
+ int await_resume();
+};
+
+class channel
+{
+ using T = int;
+
+ friend struct push_awaiter;
+ friend struct pull_awaiter;
+
+ T const* pvalue = nullptr;
+ coroutine_handle<> reader = nullptr;
+ coroutine_handle<> writer = nullptr;
+public:
+ push_awaiter push(T const& value)
+ {
+ assert(pvalue == nullptr);
+ assert(!writer);
+ pvalue = &value;
+
+ return { this };
+ }
+
+ pull_awaiter pull()
+ {
+ assert(!reader);
+
+ return { this };
+ }
+
+ void sync_push(T const& value)
+ {
+ assert(!pvalue);
+ pvalue = &value;
+ assert(reader);
+ reader();
+ assert(!pvalue);
+ reader = nullptr;
+ }
+
+ auto sync_pull()
+ {
+ while (!pvalue) goroutine::run_one();
+ auto result = *pvalue;
+ pvalue = nullptr;
+ if (writer)
+ {
+ auto wr = writer;
+ writer = nullptr;
+ wr();
+ }
+ return result;
+ }
+};
+
+void push_awaiter::await_suspend(coroutine_handle<> rh)
+{
+ ch->writer = rh;
+ if (ch->reader) goroutine::schedule(ch->reader);
+}
+
+
+bool pull_awaiter::await_ready() {
+ return !!ch->writer;
+}
+void pull_awaiter::await_suspend(coroutine_handle<> rh) {
+ ch->reader = rh;
+}
+int pull_awaiter::await_resume() {
+ auto result = *ch->pvalue;
+ ch->pvalue = nullptr;
+ if (ch->writer) {
+ //goroutine::schedule(ch->writer);
+ auto wr = ch->writer;
+ ch->writer = nullptr;
+ wr();
+ }
+ return result;
+}
+
+goroutine pusher(channel& left, channel& right)
+{
+ for (;;) {
+ auto val = co_await left.pull();
+ co_await right.push(val + 1);
+ }
+}
+
+const int N = 100; //100'000'000;
+const int repeat = 1;
+
+channel* c = new channel[N + 1];
+
+int main() {
+ for (int i = 0; i < N; ++i)
+ goroutine::go(pusher(c[i], c[i + 1]));
+
+ c[0].sync_push(0);
+ int result = c[N].sync_pull();
+
+ assert(result == 100);
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/multishot_func.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/multishot_func.sh.cpp
new file mode 100644
index 000000000000..e13196c253ea
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/multishot_func.sh.cpp
@@ -0,0 +1,91 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <cassert>
+
+using namespace std::experimental;
+
+// This file tests, multishot, movable std::function like thing using coroutine
+// for compile-time type erasure and unerasure.
+template <typename R> struct func {
+ struct Input {R a, b;};
+
+ struct promise_type {
+ Input* I;
+ R result;
+ func get_return_object() { return {this}; }
+ suspend_always initial_suspend() { return {}; }
+ suspend_never final_suspend() { return {}; }
+ void return_void() {}
+ template <typename F>
+ suspend_always yield_value(F&& f) {
+ result = f(I->a, I->b);
+ return {};
+ }
+ void unhandled_exception() {}
+ };
+
+ R operator()(Input I) {
+ h.promise().I = &I;
+ h.resume();
+ R result = h.promise().result;
+ return result;
+ };
+
+ func() {}
+ func(func &&rhs) : h(rhs.h) { rhs.h = nullptr; }
+ func(func const &) = delete;
+
+ func &operator=(func &&rhs) {
+ if (this != &rhs) {
+ if (h)
+ h.destroy();
+ h = rhs.h;
+ rhs.h = nullptr;
+ }
+ return *this;
+ }
+
+ template <typename F> static func Create(F f) {
+ for (;;) {
+ co_yield f;
+ }
+ }
+
+ template <typename F> func(F f) : func(Create(f)) {}
+
+ ~func() {
+ if (h)
+ h.destroy();
+ }
+
+private:
+ func(promise_type *promise)
+ : h(coroutine_handle<promise_type>::from_promise(*promise)) {}
+ coroutine_handle<promise_type> h;
+};
+
+int Do(int acc, int n, func<int> f) {
+ for (int i = 0; i < n; ++i)
+ acc = f({acc, i});
+ return acc;
+}
+
+int main() {
+ int result = Do(1, 10, [](int a, int b) {return a + b;});
+ assert(result == 46);
+}
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.sh.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.sh.cpp
new file mode 100644
index 000000000000..9c94f73b2a70
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.sh.cpp
@@ -0,0 +1,87 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+#include <experimental/coroutine>
+#include <vector>
+#include <cassert>
+
+using namespace std::experimental;
+
+// This file tests, one shot, movable std::function like thing using coroutine
+// for compile-time type erasure and unerasure.
+
+template <typename R> struct func {
+ struct promise_type {
+ R result;
+ func get_return_object() { return {this}; }
+ suspend_always initial_suspend() { return {}; }
+ suspend_always final_suspend() { return {}; }
+ void return_value(R v) { result = v; }
+ void unhandled_exception() {}
+ };
+
+ R operator()() {
+ h.resume();
+ R result = h.promise().result;
+ h.destroy();
+ h = nullptr;
+ return result;
+ };
+
+ func() {}
+ func(func &&rhs) : h(rhs.h) { rhs.h = nullptr; }
+ func(func const &) = delete;
+
+ func &operator=(func &&rhs) {
+ if (this != &rhs) {
+ if (h)
+ h.destroy();
+ h = rhs.h;
+ rhs.h = nullptr;
+ }
+ return *this;
+ }
+
+ template <typename F> static func Create(F f) { co_return f(); }
+
+ template <typename F> func(F f) : func(Create(f)) {}
+
+ ~func() {
+ if (h)
+ h.destroy();
+ }
+
+private:
+ func(promise_type *promise)
+ : h(coroutine_handle<promise_type>::from_promise(*promise)) {}
+ coroutine_handle<promise_type> h;
+};
+
+std::vector<int> yielded_values = {};
+int yield(int x) { yielded_values.push_back(x); return x + 1; }
+float fyield(int x) { yielded_values.push_back(x); return x + 2; }
+
+void Do1(func<int> f) { yield(f()); }
+void Do2(func<double> f) { yield(f()); }
+
+int main() {
+ Do1([] { return yield(43); });
+ assert((yielded_values == std::vector<int>{43, 44}));
+
+ yielded_values = {};
+ Do2([] { return fyield(44); });
+ assert((yielded_values == std::vector<int>{44, 46}));
+}
diff --git a/test/std/experimental/language.support/support.coroutines/includes.sh.cpp b/test/std/experimental/language.support/support.coroutines/includes.sh.cpp
new file mode 100644
index 000000000000..f9d8a572256c
--- /dev/null
+++ b/test/std/experimental/language.support/support.coroutines/includes.sh.cpp
@@ -0,0 +1,31 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+// REQUIRES: fcoroutines-ts
+
+// RUN: %build -fcoroutines-ts
+// RUN: %run
+
+// <experimental/coroutine>
+
+// Test that <experimental/coroutine> includes <new>
+
+#include <experimental/coroutine>
+
+
+
+int main(){
+ // std::nothrow is not implicitly defined by the compiler when the include is
+ // missing, unlike other parts of <new>. Therefore we use std::nothrow to
+ // test for #include <new>
+ (void)std::nothrow;
+
+}
diff --git a/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op_astrk/arrow.pass.cpp b/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op_astrk/arrow.pass.cpp
deleted file mode 100644
index e3bf5e2bd84f..000000000000
--- a/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op_astrk/arrow.pass.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <iterator>
-
-// istreambuf_iterator
-
-// pointer operator->() const;
-
-#include <iostream>
-#include <sstream>
-#include <streambuf>
-
-typedef char C;
-int main ()
-{
- std::istringstream s("filename");
- std::istreambuf_iterator<char> i(s);
-
- (*i).~C(); // This is well-formed...
- i->~C(); // ... so this should be supported!
-}
diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
index 8de5fc7bab85..31add9df27a4 100644
--- a/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
+++ b/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
@@ -24,6 +24,7 @@ test(S s, typename S::difference_type pos, S expected)
typename S::const_iterator p = s.begin() + pos;
typename S::iterator i = s.erase(p);
LIBCPP_ASSERT(s.__invariants());
+ assert(s[s.size()] == typename S::value_type());
assert(s == expected);
assert(i - s.begin() == pos);
}
diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
index e4fe2cdfd022..858d3754e9da 100644
--- a/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
+++ b/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
@@ -25,6 +25,7 @@ test(S s, typename S::difference_type pos, typename S::difference_type n, S expe
typename S::const_iterator last = s.cbegin() + pos + n;
typename S::iterator i = s.erase(first, last);
LIBCPP_ASSERT(s.__invariants());
+ assert(s[s.size()] == typename S::value_type());
assert(s == expected);
assert(i - s.begin() == pos);
}
diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
index 64f8e506b13e..8424b5429cea 100644
--- a/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
+++ b/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
@@ -23,6 +23,7 @@ test(S s, S expected)
{
s.pop_back();
LIBCPP_ASSERT(s.__invariants());
+ assert(s[s.size()] == typename S::value_type());
assert(s == expected);
}
diff --git a/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
index eb6be202a350..2c900bb315bc 100644
--- a/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
+++ b/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
@@ -29,6 +29,7 @@ test(S s, typename S::size_type pos, typename S::size_type n, S expected)
{
s.erase(pos, n);
LIBCPP_ASSERT(s.__invariants());
+ assert(s[s.size()] == typename S::value_type());
assert(s == expected);
}
#ifndef TEST_HAS_NO_EXCEPTIONS
@@ -58,6 +59,7 @@ test(S s, typename S::size_type pos, S expected)
{
s.erase(pos);
LIBCPP_ASSERT(s.__invariants());
+ assert(s[s.size()] == typename S::value_type());
assert(s == expected);
}
#ifndef TEST_HAS_NO_EXCEPTIONS
@@ -83,6 +85,7 @@ test(S s, S expected)
{
s.erase();
LIBCPP_ASSERT(s.__invariants());
+ assert(s[s.size()] == typename S::value_type());
assert(s == expected);
}
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp
index 4e73d8064317..82d63ecada48 100644
--- a/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct_pair.pass.cpp
@@ -39,6 +39,7 @@ void test_no_inner_alloc()
using SA = std::scoped_allocator_adaptor<Alloc>;
static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ assert(ptr);
Alloc CA(P);
SA A(CA);
A.construct(ptr);
@@ -61,6 +62,7 @@ void test_no_inner_alloc()
using SA = std::scoped_allocator_adaptor<Alloc>;
static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ assert(ptr);
Alloc CA(P);
SA A(CA);
A.construct(ptr);
@@ -77,7 +79,6 @@ void test_no_inner_alloc()
void test_with_inner_alloc()
{
- using VoidAlloc1 = CountingAllocator<void, 1>;
using VoidAlloc2 = CountingAllocator<void, 2>;
AllocController POuter;
@@ -93,6 +94,7 @@ void test_with_inner_alloc()
static_assert(!std::uses_allocator<T, Outer>::value, "");
static_assert(std::uses_allocator<T, Inner>::value, "");
Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ assert(ptr);
Outer O(POuter);
Inner I(PInner);
SA A(O, I);
@@ -119,6 +121,7 @@ void test_with_inner_alloc()
static_assert(!std::uses_allocator<T, Outer>::value, "");
static_assert(std::uses_allocator<T, Inner>::value, "");
Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
+ assert(ptr);
Outer O(POuter);
Inner I(PInner);
SA A(O, I);
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
index 2a7ac9979d02..f8f73f771356 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
@@ -45,6 +45,25 @@ struct Foo
virtual ~Foo() = default;
};
+#ifdef _LIBCPP_VERSION
+struct Result {};
+static Result theFunction() { return Result(); }
+static int resultDeletorCount;
+static void resultDeletor(Result (*pf)()) {
+ assert(pf == theFunction);
+ ++resultDeletorCount;
+}
+
+void test_pointer_to_function() {
+ { // https://bugs.llvm.org/show_bug.cgi?id=27566
+ std::shared_ptr<Result()> x(&theFunction, &resultDeletor);
+ std::shared_ptr<Result()> y(theFunction, resultDeletor);
+ }
+ assert(resultDeletorCount == 2);
+}
+#else // _LIBCPP_VERSION
+void test_pointer_to_function() {}
+#endif // _LIBCPP_VERSION
int main()
{
@@ -66,6 +85,8 @@ int main()
assert(p2.get());
}
+ test_pointer_to_function();
+
#if TEST_STD_VER >= 11
nc = globalMemCounter.outstanding_new;
{
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
index 76c1fb82b866..6b4283a2854b 100644
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -32,6 +32,16 @@ void test(InitArgs&&... args)
assert(*lhs == *rhs);
}
+template <class T, class ...InitArgs>
+constexpr bool constexpr_test(InitArgs&&... args)
+{
+ static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ optional<T> lhs = rhs;
+ return (lhs.has_value() == rhs.has_value()) &&
+ (lhs.has_value() ? *lhs == *rhs : true);
+}
+
void test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
struct Z {
@@ -108,6 +118,9 @@ int main()
{
test<int>();
test<int>(3);
+ static_assert(constexpr_test<int>(), "" );
+ static_assert(constexpr_test<int>(3), "" );
+
{
const optional<const int> o(42);
optional<const int> o2(o);
diff --git a/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
index 09aaa0561b51..82acdd9d7758 100644
--- a/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
+++ b/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -41,6 +41,17 @@ void test(InitArgs&&... args)
assert(*lhs == *orig);
}
+template <class T, class ...InitArgs>
+constexpr bool constexpr_test(InitArgs&&... args)
+{
+ static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
+ const optional<T> orig(std::forward<InitArgs>(args)...);
+ optional<T> rhs(orig);
+ optional<T> lhs = std::move(rhs);
+ return (lhs.has_value() == orig.has_value()) &&
+ (lhs.has_value() ? *lhs == *orig : true);
+}
+
void test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
struct Z {
@@ -144,6 +155,9 @@ int main()
{
test<int>();
test<int>(3);
+ static_assert(constexpr_test<int>(), "" );
+ static_assert(constexpr_test<int>(3), "" );
+
{
optional<const int> o(42);
optional<const int> o2(std::move(o));
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
index a695df14ef62..3b20c369c638 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
@@ -149,7 +149,7 @@ constexpr bool test_constexpr_copy_ctor_extension_imp(
}
void test_constexpr_copy_ctor_extension() {
-#if defined(_LIBCPP_VER) || defined(_MSVC_STL_VER)
+ // NOTE: This test is for not yet standardized behavior.
using V = std::variant<long, void*, const int>;
#ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_destructible<V>::value, "");
@@ -163,7 +163,6 @@ void test_constexpr_copy_ctor_extension() {
static_assert(test_constexpr_copy_ctor_extension_imp<0>(V(42l)), "");
static_assert(test_constexpr_copy_ctor_extension_imp<1>(V(nullptr)), "");
static_assert(test_constexpr_copy_ctor_extension_imp<2>(V(101)), "");
-#endif
}
int main() {
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
index b8ca6f9ef27a..a5de1f77334e 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
@@ -186,7 +186,7 @@ constexpr bool test_constexpr_ctor_extension_imp(
}
void test_constexpr_move_ctor_extension() {
-#if defined(_LIBCPP_VER) || defined(_MSVC_STL_VER)
+ // NOTE: This test is for not yet standardized behavior.
using V = std::variant<long, void*, const int>;
#ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE
static_assert(std::is_trivially_destructible<V>::value, "");
@@ -201,7 +201,6 @@ void test_constexpr_move_ctor_extension() {
static_assert(test_constexpr_ctor_extension_imp<0>(V(42l)), "");
static_assert(test_constexpr_ctor_extension_imp<1>(V(nullptr)), "");
static_assert(test_constexpr_ctor_extension_imp<2>(V(101)), "");
-#endif
}
int main() {