Index: vendor/libc++/dist/include/experimental/coroutine =================================================================== --- vendor/libc++/dist/include/experimental/coroutine (revision 319235) +++ vendor/libc++/dist/include/experimental/coroutine (revision 319236) @@ -1,270 +1,294 @@ // -*- C++ -*- //===----------------------------- coroutine -----------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef _LIBCPP_EXPERIMENTAL_COROUTINE #define _LIBCPP_EXPERIMENTAL_COROUTINE /** experimental/coroutine synopsis // C++next namespace std { namespace experimental { inline namespace coroutines_v1 { // 18.11.1 coroutine traits template class coroutine_traits; // 18.11.2 coroutine handle template class coroutine_handle; // 18.11.2.7 comparison operators: bool operator==(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; bool operator!=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; bool operator<(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; bool operator<=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; bool operator>=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; bool operator>(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; // 18.11.3 trivial awaitables struct suspend_never; struct suspend_always; // 18.11.2.8 hash support: template struct hash; template struct hash>; } // namespace coroutines_v1 } // namespace experimental } // namespace std */ #include #include #include #include #include // for hash #include #include #include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif #ifdef _LIBCPP_HAS_NO_COROUTINES # if defined(_LIBCPP_WARNING) _LIBCPP_WARNING(" cannot be used with this compiler") # else # warning cannot be used with this compiler # endif #endif #ifndef _LIBCPP_HAS_NO_COROUTINES _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES template struct __coroutine_traits_sfinae {}; template struct __coroutine_traits_sfinae< _Tp, typename __void_t::type> { using promise_type = typename _Tp::promise_type; }; template struct _LIBCPP_TEMPLATE_VIS coroutine_traits : public __coroutine_traits_sfinae<_Ret> { }; template class _LIBCPP_TEMPLATE_VIS coroutine_handle; template <> class _LIBCPP_TEMPLATE_VIS coroutine_handle { public: _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR coroutine_handle() _NOEXCEPT : __handle_(nullptr) {} _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR coroutine_handle(nullptr_t) _NOEXCEPT : __handle_(nullptr) {} _LIBCPP_ALWAYS_INLINE coroutine_handle& operator=(nullptr_t) _NOEXCEPT { __handle_ = nullptr; return *this; } _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR void* address() const _NOEXCEPT { return __handle_; } _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return __handle_; } _LIBCPP_ALWAYS_INLINE void operator()() { resume(); } _LIBCPP_ALWAYS_INLINE void resume() { _LIBCPP_ASSERT(__is_suspended(), "resume() can only be called on suspended coroutines"); _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); __builtin_coro_resume(__handle_); } _LIBCPP_ALWAYS_INLINE void destroy() { _LIBCPP_ASSERT(__is_suspended(), "destroy() can only be called on suspended coroutines"); __builtin_coro_destroy(__handle_); } _LIBCPP_ALWAYS_INLINE bool done() const { _LIBCPP_ASSERT(__is_suspended(), "done() can only be called on suspended coroutines"); return __builtin_coro_done(__handle_); } public: _LIBCPP_ALWAYS_INLINE static coroutine_handle from_address(void* __addr) _NOEXCEPT { coroutine_handle __tmp; __tmp.__handle_ = __addr; return __tmp; } + // FIXME: Should from_address(nullptr) be allowed? + _LIBCPP_ALWAYS_INLINE + static coroutine_handle from_address(nullptr_t) _NOEXCEPT { + return coroutine_handle(nullptr); + } + + template + static coroutine_handle from_address(_Tp*) { + static_assert(_CallIsValid, + "coroutine_handle::from_address cannot be called with " + "non-void pointers"); + } + private: bool __is_suspended() const _NOEXCEPT { // FIXME actually implement a check for if the coro is suspended. return __handle_; } template friend class coroutine_handle; void* __handle_; }; // 18.11.2.7 comparison operators: inline _LIBCPP_ALWAYS_INLINE bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { return __x.address() == __y.address(); } inline _LIBCPP_ALWAYS_INLINE bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { return !(__x == __y); } inline _LIBCPP_ALWAYS_INLINE bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { return less()(__x.address(), __y.address()); } inline _LIBCPP_ALWAYS_INLINE bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { return __y < __x; } inline _LIBCPP_ALWAYS_INLINE bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { return !(__x > __y); } inline _LIBCPP_ALWAYS_INLINE bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { return !(__x < __y); } template class _LIBCPP_TEMPLATE_VIS coroutine_handle : public coroutine_handle<> { using _Base = coroutine_handle<>; public: #ifndef _LIBCPP_CXX03_LANG // 18.11.2.1 construct/reset using coroutine_handle<>::coroutine_handle; #else _LIBCPP_ALWAYS_INLINE coroutine_handle() _NOEXCEPT : _Base() {} _LIBCPP_ALWAYS_INLINE coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {} #endif _LIBCPP_INLINE_VISIBILITY coroutine_handle& operator=(nullptr_t) _NOEXCEPT { _Base::operator=(nullptr); return *this; } _LIBCPP_INLINE_VISIBILITY _Promise& promise() const { return *reinterpret_cast<_Promise*>( __builtin_coro_promise(this->__handle_, __alignof(_Promise), false)); } public: _LIBCPP_ALWAYS_INLINE static coroutine_handle from_address(void* __addr) _NOEXCEPT { coroutine_handle __tmp; __tmp.__handle_ = __addr; return __tmp; } // NOTE: this overload isn't required by the standard but is needed so // the deleted _Promise* overload doesn't make from_address(nullptr) // ambiguous. // FIXME: should from_address work with nullptr? _LIBCPP_ALWAYS_INLINE static coroutine_handle from_address(nullptr_t) _NOEXCEPT { - return {}; + return coroutine_handle(nullptr); } - // from_address cannot be used with the coroutines promise type. - static coroutine_handle from_address(_Promise*) = delete; + template + static coroutine_handle from_address(_Tp*) { + static_assert(_CallIsValid, + "coroutine_handle::from_address cannot be called with " + "non-void pointers"); + } + + template + static coroutine_handle from_address(_Promise*) { + static_assert(_CallIsValid, + "coroutine_handle::from_address cannot be used with " + "pointers to the coroutine's promise type; use 'from_promise' instead"); + } _LIBCPP_ALWAYS_INLINE static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT { coroutine_handle __tmp; __tmp.__handle_ = __builtin_coro_promise(_VSTD::addressof(__promise), __alignof(_Promise), true); return __tmp; } }; struct _LIBCPP_TYPE_VIS suspend_never { _LIBCPP_ALWAYS_INLINE bool await_ready() const _NOEXCEPT { return true; } _LIBCPP_ALWAYS_INLINE void await_suspend(coroutine_handle<>) const _NOEXCEPT {} _LIBCPP_ALWAYS_INLINE void await_resume() const _NOEXCEPT {} }; struct _LIBCPP_TYPE_VIS suspend_always { _LIBCPP_ALWAYS_INLINE bool await_ready() const _NOEXCEPT { return false; } _LIBCPP_ALWAYS_INLINE void await_suspend(coroutine_handle<>) const _NOEXCEPT {} _LIBCPP_ALWAYS_INLINE void await_resume() const _NOEXCEPT {} }; _LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES _LIBCPP_BEGIN_NAMESPACE_STD template struct hash<_VSTD_CORO::coroutine_handle<_Tp> > { using __arg_type = _VSTD_CORO::coroutine_handle<_Tp>; _LIBCPP_INLINE_VISIBILITY size_t operator()(__arg_type const& __v) const _NOEXCEPT {return hash()(__v.address());} }; _LIBCPP_END_NAMESPACE_STD #endif // !defined(_LIBCPP_HAS_NO_COROUTINES) #endif /* _LIBCPP_EXPERIMENTAL_COROUTINE */ Index: vendor/libc++/dist/include/module.modulemap =================================================================== --- vendor/libc++/dist/include/module.modulemap (revision 319235) +++ vendor/libc++/dist/include/module.modulemap (revision 319236) @@ -1,610 +1,611 @@ // define the module for __config outside of the top level 'std' module // since __config may be included from C headers which may create an // include cycle. module std_config [system] [extern_c] { header "__config" } module std [system] { export std_config // FIXME: The standard does not require that each of these submodules // re-exports its imported modules. We should provide an alternative form of // export that issues a warning if a name from the submodule is used, and // use that to provide a 'strict mode' for libc++. // Deprecated C-compatibility headers. These can all be included from within // an 'extern "C"' context. module depr [extern_c] { // provided by C library. module ctype_h { header "ctype.h" export * } module errno_h { header "errno.h" export * } // provided by C library. // provided by compiler or C library. module inttypes_h { header "inttypes.h" export stdint_h export * } // provided by compiler. // provided by compiler or C library. module locale_h { header "locale.h" export * } module math_h { header "math.h" export * } module setjmp_h { header "setjmp.h" export * } // FIXME: is missing. // provided by C library. // provided by compiler. // provided by compiler. module stddef_h { // 's __need_* macros require textual inclusion. textual header "stddef.h" } module stdint_h { header "stdint.h" export * // FIXME: This module only exists on OS X and for some reason the // wildcard above doesn't export it. export Darwin.C.stdint } module stdio_h { // 's __need_* macros require textual inclusion. textual header "stdio.h" export * export Darwin.C.stdio } module stdlib_h { // 's __need_* macros require textual inclusion. textual header "stdlib.h" export * } module string_h { header "string.h" export * } // FIXME: is missing. // provided by C library. module wchar_h { // 's __need_* macros require textual inclusion. textual header "wchar.h" export * } module wctype_h { header "wctype.h" export * } } // and are not C headers in any real sense, do not // allow their use in extern "C" contexts. module complex_h { header "complex.h" export ccomplex export * } module tgmath_h { header "tgmath.h" export ccomplex export cmath export * } // C compatibility headers. module compat { module cassert { // 's use of NDEBUG requires textual inclusion. textual header "cassert" } module ccomplex { header "ccomplex" export complex export * } module cctype { header "cctype" export * } module cerrno { header "cerrno" export * } module cfenv { header "cfenv" export * } module cfloat { header "cfloat" export * } module cinttypes { header "cinttypes" export cstdint export * } module ciso646 { header "ciso646" export * } module climits { header "climits" export * } module clocale { header "clocale" export * } module cmath { header "cmath" export * } module csetjmp { header "csetjmp" export * } module csignal { header "csignal" export * } // FIXME: is missing. module cstdarg { header "cstdarg" export * } module cstdbool { header "cstdbool" export * } module cstddef { header "cstddef" export * } module cstdint { header "cstdint" export depr.stdint_h export * } module cstdio { header "cstdio" export * } module cstdlib { header "cstdlib" export * } module cstring { header "cstring" export * } module ctgmath { header "ctgmath" export ccomplex export cmath export * } module ctime { header "ctime" export * } // FIXME: is missing. module cwchar { header "cwchar" export depr.stdio_h export * } module cwctype { header "cwctype" export * } } module algorithm { header "algorithm" export initializer_list export * } module any { header "any" export * } module array { header "array" export initializer_list export * } module atomic { header "atomic" export * } module bitset { header "bitset" export string export iosfwd export * } // No submodule for cassert. It fundamentally needs repeated, textual inclusion. module chrono { header "chrono" export * } module codecvt { header "codecvt" export * } module complex { header "complex" export * } module condition_variable { header "condition_variable" export * } module deque { header "deque" export initializer_list export * } module exception { header "exception" export * } module forward_list { header "forward_list" export initializer_list export * } module fstream { header "fstream" export * } module functional { header "functional" export * } module future { header "future" export * } module initializer_list { header "initializer_list" export * } module iomanip { header "iomanip" export * } module ios { header "ios" export iosfwd export * } module iosfwd { header "iosfwd" export * } module iostream { header "iostream" export ios export streambuf export istream export ostream export * } module istream { header "istream" // FIXME: should re-export ios, streambuf? export * } module iterator { header "iterator" export * } module limits { header "limits" export * } module list { header "list" export initializer_list export * } module locale { header "locale" export * } module map { header "map" export initializer_list export * } module memory { header "memory" export * } module mutex { header "mutex" export * } module new { header "new" export * } module numeric { header "numeric" export * } module optional { header "optional" export * } module ostream { header "ostream" // FIXME: should re-export ios, streambuf? export * } module queue { header "queue" export initializer_list export * } module random { header "random" export initializer_list export * } module ratio { header "ratio" export * } module regex { header "regex" export initializer_list export * } module scoped_allocator { header "scoped_allocator" export * } module set { header "set" export initializer_list export * } module sstream { header "sstream" // FIXME: should re-export istream, ostream, ios, streambuf, string? export * } module stack { header "stack" export initializer_list export * } module stdexcept { header "stdexcept" export * } module streambuf { header "streambuf" export * } module string { header "string" export initializer_list export string_view export __string export * } module string_view { header "string_view" export initializer_list export __string export * } module strstream { header "strstream" export * } module system_error { header "system_error" export * } module thread { header "thread" export * } module tuple { header "tuple" export * } module type_traits { header "type_traits" export * } module typeindex { header "typeindex" export * } module typeinfo { header "typeinfo" export * } module unordered_map { header "unordered_map" export initializer_list export * } module unordered_set { header "unordered_set" export initializer_list export * } module utility { header "utility" export initializer_list export * } module valarray { header "valarray" export initializer_list export * } module variant { header "variant" export * } module vector { header "vector" export initializer_list export * } // FIXME: These should be private. module __bit_reference { header "__bit_reference" export * } module __debug { header "__debug" export * } module __functional_base { header "__functional_base" export * } module __hash_table { header "__hash_table" export * } module __locale { header "__locale" export * } module __mutex_base { header "__mutex_base" export * } module __split_buffer { header "__split_buffer" export * } module __sso_allocator { header "__sso_allocator" export * } module __std_stream { header "__std_stream" export * } module __string { header "__string" export * } module __tree { header "__tree" export * } module __tuple { header "__tuple" export * } module __undef_min_max { header "__undef_min_max" export * } module experimental { requires cplusplus11 module algorithm { header "experimental/algorithm" export * } module any { header "experimental/any" export * } module chrono { header "experimental/chrono" export * } module coroutine { + requires coroutines header "experimental/coroutine" export * } module deque { header "experimental/deque" export * } module dynarray { header "experimental/dynarray" export * } module filesystem { header "experimental/filesystem" export * } module forward_list { header "experimental/forward_list" export * } module functional { header "experimental/functional" export * } module iterator { header "experimental/iterator" export * } module list { header "experimental/list" export * } module map { header "experimental/map" export * } module memory_resource { header "experimental/memory_resource" export * } module numeric { header "experimental/numeric" export * } module optional { header "experimental/optional" export * } module propagate_const { header "experimental/propagate_const" export * } module ratio { header "experimental/ratio" export * } module regex { header "experimental/regex" export * } module set { header "experimental/set" export * } module string { header "experimental/string" export * } module string_view { header "experimental/string_view" export * } module system_error { header "experimental/system_error" export * } module tuple { header "experimental/tuple" export * } module type_traits { header "experimental/type_traits" export * } module unordered_map { header "experimental/unordered_map" export * } module unordered_set { header "experimental/unordered_set" export * } module utility { header "experimental/utility" export * } module vector { header "experimental/vector" export * } // FIXME these should be private module __memory { header "experimental/__memory" export * } } // end experimental } Index: vendor/libc++/dist/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.fail.cpp =================================================================== --- vendor/libc++/dist/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.fail.cpp (nonexistent) +++ vendor/libc++/dist/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.fail.cpp (revision 319236) @@ -0,0 +1,46 @@ +// -*- 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 +// + +// template +// struct coroutine_handle; + +// static coroutine_handle from_address(void*) noexcept + +// Test that `from_address` is explicitly ill-formed when called with a typed +// pointer. The user cannot possibly have a typed pointer to the coroutine. +// FIXME: This behavior is an extension, and should upstreamed into the TS or +// the test removed if the TS changes are rejected. + +#include +#include +#include + +namespace coro = std::experimental; + +int main() +{ + { + using H = coro::coroutine_handle<>; + // expected-error@experimental/coroutine:* 3 {{coroutine_handle::from_address cannot be called with non-void pointers}} + H::from_address((int*)nullptr); // expected-note {{requested here}} + H::from_address((const void*)nullptr); // expected-note {{requested here}} + H::from_address((const char*)nullptr); // expected-note {{requested here}} + } + { + using H = coro::coroutine_handle; + // expected-error@experimental/coroutine:* 1 {{static_assert failed "coroutine_handle::from_address cannot be used with pointers to the coroutine's promise type; use 'from_promise' instead"}} + H::from_address((const char*)nullptr); // expected-note {{requested here}} + // expected-error@experimental/coroutine:* 1 {{coroutine_handle::from_address cannot be called with non-void pointers}} + H::from_address((int*)nullptr); // expected-note {{requested here}} + } +} Property changes on: vendor/libc++/dist/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.fail.cpp ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: vendor/libc++/dist/test/std/experimental/language.support/support.coroutines/lit.local.cfg =================================================================== --- vendor/libc++/dist/test/std/experimental/language.support/support.coroutines/lit.local.cfg (nonexistent) +++ vendor/libc++/dist/test/std/experimental/language.support/support.coroutines/lit.local.cfg (revision 319236) @@ -0,0 +1,9 @@ +# If the compiler doesn't support coroutines mark all of the tests under +# this directory as unsupported. Otherwise add the required `-fcoroutines-ts` +# flag. +if 'fcoroutines-ts' not in config.available_features: + config.unsupported = True +else: + import copy + config.test_format.cxx = copy.deepcopy(config.test_format.cxx) + config.test_format.cxx.compile_flags += ['-fcoroutines-ts']