aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur O'Dwyer <arthur.j.odwyer@gmail.com>2021-12-13 19:21:38 -0500
committerArthur O'Dwyer <arthur.j.odwyer@gmail.com>2021-12-22 12:29:42 -0500
commitcb8a0b07974eb6a6aa681c30ce694e13b33a3db5 (patch)
treeb1c052930f3dc08be368aed049dd358e7a54461d
parent4a10457d33e92f2e024f6d024d168ddcd49c3a59 (diff)
downloadllvm-cb8a0b07974eb6a6aa681c30ce694e13b33a3db5.zip
llvm-cb8a0b07974eb6a6aa681c30ce694e13b33a3db5.tar.gz
llvm-cb8a0b07974eb6a6aa681c30ce694e13b33a3db5.tar.bz2
[libc++] [ranges] Introduce _LIBCPP_AUTO_CAST(x) for auto(x).
Clang is gaining `auto(x)` support in D113393; sadly there seems to be no feature-test macro for it. Zhihao is opening a core issue for that macro. Use `_LIBCPP_AUTO_CAST` where C++20 specifies we should use `auto(x)`; stop using `__decay_copy(x)` in those places. In fact, remove `__decay_copy` entirely. As of C++20, it's purely a paper specification tool signifying "Return just `x`, but it was perfect-forwarded, so we understand you're going to have to call its move-constructor sometimes." I believe there's no reason we'd ever need to do its operation explicitly in code. This heisenbugs away a test failure on MinGW; see D112214. Differential Revision: https://reviews.llvm.org/D115686
-rw-r--r--libcxx/docs/Status/Cxx2bPapers.csv2
-rw-r--r--libcxx/include/CMakeLists.txt2
-rw-r--r--libcxx/include/__ranges/access.h27
-rw-r--r--libcxx/include/__ranges/all.h6
-rw-r--r--libcxx/include/__ranges/size.h18
-rw-r--r--libcxx/include/__utility/auto_cast.h (renamed from libcxx/include/__utility/decay_copy.h)21
-rw-r--r--libcxx/include/future10
-rw-r--r--libcxx/include/module.modulemap2
-rw-r--r--libcxx/include/thread5
-rw-r--r--libcxx/include/utility1
-rw-r--r--libcxx/test/libcxx/diagnostics/detail.headers/utility/auto_cast.module.verify.cpp (renamed from libcxx/test/libcxx/diagnostics/detail.headers/utility/decay_copy.module.verify.cpp)4
-rw-r--r--libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp31
-rw-r--r--libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp46
-rw-r--r--libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp2
-rw-r--r--libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp2
15 files changed, 80 insertions, 99 deletions
diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index 8a5b759..7a76e1f 100644
--- a/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/libcxx/docs/Status/Cxx2bPapers.csv
@@ -25,7 +25,7 @@
"","","","","",""
"`P0288R9 <https://wg21.link/P0288R9>`__","LWG","``any_invocable``","October 2021","",""
"`P0798R8 <https://wg21.link/P0798R8>`__","LWG","Monadic operations for ``std::optional``","October 2021","|Complete|","14.0"
-"`P0849R8 <https://wg21.link/P0849R8>`__","LWG","``auto(x)``: ``DECAY_COPY`` in the language","October 2021","",""
+"`P0849R8 <https://wg21.link/P0849R8>`__","LWG","``auto(x)``: ``DECAY_COPY`` in the language","October 2021","|Complete|","14.0"
"`P1072R10 <https://wg21.link/P1072R10>`__","LWG","``basic_string::resize_and_overwrite``","October 2021","",""
"`P1147R1 <https://wg21.link/P1147R1>`__","LWG","Printing ``volatile`` Pointers","October 2021","|Complete|","14.0"
"`P1272R4 <https://wg21.link/P1272R4>`__","LWG","Byteswapping for fun&&nuf","October 2021","|Complete|","14.0"
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 76eed6f..180f7d4 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -360,8 +360,8 @@ set(files
__tuple
__undef_macros
__utility/as_const.h
+ __utility/auto_cast.h
__utility/cmp.h
- __utility/decay_copy.h
__utility/declval.h
__utility/exchange.h
__utility/forward.h
diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h
index d54b331..c58849f 100644
--- a/libcxx/include/__ranges/access.h
+++ b/libcxx/include/__ranges/access.h
@@ -14,8 +14,7 @@
#include <__iterator/readable_traits.h>
#include <__ranges/enable_borrowed_range.h>
#include <__utility/as_const.h>
-#include <__utility/decay_copy.h>
-#include <__utility/forward.h>
+#include <__utility/auto_cast.h>
#include <concepts>
#include <type_traits>
@@ -39,7 +38,7 @@ namespace ranges::__begin {
concept __member_begin =
__can_borrow<_Tp> &&
requires(_Tp&& __t) {
- { _VSTD::__decay_copy(__t.begin()) } -> input_or_output_iterator;
+ { _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator;
};
void begin(auto&) = delete;
@@ -51,7 +50,7 @@ namespace ranges::__begin {
__can_borrow<_Tp> &&
__class_or_enum<remove_cvref_t<_Tp> > &&
requires(_Tp && __t) {
- { _VSTD::__decay_copy(begin(__t)) } -> input_or_output_iterator;
+ { _LIBCPP_AUTO_CAST(begin(__t)) } -> input_or_output_iterator;
};
struct __fn {
@@ -65,17 +64,17 @@ namespace ranges::__begin {
template <class _Tp>
requires __member_begin<_Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(_VSTD::__decay_copy(__t.begin())))
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.begin())))
{
- return __t.begin();
+ return _LIBCPP_AUTO_CAST(__t.begin());
}
template <class _Tp>
requires __unqualified_begin<_Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(_VSTD::__decay_copy(begin(__t))))
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t))))
{
- return begin(__t);
+ return _LIBCPP_AUTO_CAST(begin(__t));
}
void operator()(auto&&) const = delete;
@@ -98,7 +97,7 @@ namespace ranges::__end {
__can_borrow<_Tp> &&
requires(_Tp&& __t) {
typename iterator_t<_Tp>;
- { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).end()) } -> sentinel_for<iterator_t<_Tp> >;
+ { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp> >;
};
void end(auto&) = delete;
@@ -111,7 +110,7 @@ namespace ranges::__end {
__class_or_enum<remove_cvref_t<_Tp> > &&
requires(_Tp && __t) {
typename iterator_t<_Tp>;
- { _VSTD::__decay_copy(end(_VSTD::forward<_Tp>(__t))) } -> sentinel_for<iterator_t<_Tp> >;
+ { _LIBCPP_AUTO_CAST(end(__t)) } -> sentinel_for<iterator_t<_Tp> >;
};
class __fn {
@@ -126,17 +125,17 @@ namespace ranges::__end {
template <class _Tp>
requires __member_end<_Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(_VSTD::__decay_copy(__t.end())))
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.end())))
{
- return _VSTD::forward<_Tp>(__t).end();
+ return _LIBCPP_AUTO_CAST(__t.end());
}
template <class _Tp>
requires __unqualified_end<_Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(_VSTD::__decay_copy(end(__t))))
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t))))
{
- return end(__t);
+ return _LIBCPP_AUTO_CAST(end(__t));
}
void operator()(auto&&) const = delete;
diff --git a/libcxx/include/__ranges/all.h b/libcxx/include/__ranges/all.h
index affe13e..ccc7725 100644
--- a/libcxx/include/__ranges/all.h
+++ b/libcxx/include/__ranges/all.h
@@ -17,7 +17,7 @@
#include <__ranges/range_adaptor.h>
#include <__ranges/ref_view.h>
#include <__ranges/subrange.h>
-#include <__utility/decay_copy.h>
+#include <__utility/auto_cast.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
#include <type_traits>
@@ -38,9 +38,9 @@ namespace __all {
requires ranges::view<decay_t<_Tp>>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
constexpr auto operator()(_Tp&& __t) const
- noexcept(noexcept(_VSTD::__decay_copy(_VSTD::forward<_Tp>(__t))))
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(_VSTD::forward<_Tp>(__t))))
{
- return _VSTD::forward<_Tp>(__t);
+ return _LIBCPP_AUTO_CAST(_VSTD::forward<_Tp>(__t));
}
template<class _Tp>
diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h
index af0a847..c37467e 100644
--- a/libcxx/include/__ranges/size.h
+++ b/libcxx/include/__ranges/size.h
@@ -13,8 +13,7 @@
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
-#include <__utility/decay_copy.h>
-#include <__utility/forward.h>
+#include <__utility/auto_cast.h>
#include <concepts>
#include <type_traits>
@@ -26,7 +25,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
-// clang-format off
namespace ranges {
template<class>
inline constexpr bool disable_sized_range = false;
@@ -41,7 +39,7 @@ namespace __size {
template <class _Tp>
concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) {
- { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).size()) } -> __integer_like;
+ { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;
};
template <class _Tp>
@@ -50,7 +48,7 @@ namespace __size {
!__member_size<_Tp> &&
__class_or_enum<remove_cvref_t<_Tp>> &&
requires(_Tp&& __t) {
- { _VSTD::__decay_copy(size(_VSTD::forward<_Tp>(__t))) } -> __integer_like;
+ { _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;
};
template <class _Tp>
@@ -76,14 +74,14 @@ namespace __size {
template <__member_size _Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(_VSTD::forward<_Tp>(__t).size())) {
- return _VSTD::forward<_Tp>(__t).size();
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.size()))) {
+ return _LIBCPP_AUTO_CAST(__t.size());
}
template <__unqualified_size _Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
- noexcept(noexcept(size(_VSTD::forward<_Tp>(__t)))) {
- return size(_VSTD::forward<_Tp>(__t));
+ noexcept(noexcept(_LIBCPP_AUTO_CAST(size(__t)))) {
+ return _LIBCPP_AUTO_CAST(size(__t));
}
template<__difference _Tp>
@@ -118,8 +116,6 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
-// clang-format off
-
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__utility/decay_copy.h b/libcxx/include/__utility/auto_cast.h
index 32238e1..5c368e0 100644
--- a/libcxx/include/__utility/decay_copy.h
+++ b/libcxx/include/__utility/auto_cast.h
@@ -7,29 +7,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___UTILITY_DECAY_COPY_H
-#define _LIBCPP___UTILITY_DECAY_COPY_H
+#ifndef _LIBCPP___UTILITY_AUTO_CAST_H
+#define _LIBCPP___UTILITY_AUTO_CAST_H
#include <__config>
-#include <__utility/forward.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
-_LIBCPP_BEGIN_NAMESPACE_STD
+#define _LIBCPP_AUTO_CAST(expr) static_cast<typename decay<decltype((expr))>::type>(expr)
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
-typename decay<_Tp>::type __decay_copy(_Tp&& __t)
-#if _LIBCPP_STD_VER > 17
- noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>)
-#endif
-{
- return _VSTD::forward<_Tp>(__t);
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___UTILITY_DECAY_COPY_H
+#endif // _LIBCPP___UTILITY_AUTO_CAST_H
diff --git a/libcxx/include/future b/libcxx/include/future
index 99df883..6b666a7 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -366,7 +366,7 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
#include <__debug>
#include <__memory/allocator_arg_t.h>
#include <__memory/uses_allocator.h>
-#include <__utility/decay_copy.h>
+#include <__utility/auto_cast.h>
#include <__utility/forward.h>
#include <chrono>
#include <exception>
@@ -2207,16 +2207,16 @@ async(launch __policy, _Fp&& __f, _Args&&... __args)
{
#endif
if (__does_policy_contain(__policy, launch::async))
- return _VSTD::__make_async_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
- _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
+ return _VSTD::__make_async_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
+ _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch ( ... ) { if (__policy == launch::async) throw ; }
#endif
if (__does_policy_contain(__policy, launch::deferred))
- return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
- _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
+ return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
+ _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
return future<_Rp>{};
}
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 4194a7f..1dc6db4 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -921,8 +921,8 @@ module std [system] {
module __utility {
module as_const { private header "__utility/as_const.h" }
+ module auto_cast { private header "__utility/auto_cast.h" }
module cmp { private header "__utility/cmp.h" }
- module decay_copy { private header "__utility/decay_copy.h" }
module declval { private header "__utility/declval.h" }
module exchange { private header "__utility/exchange.h" }
module forward { private header "__utility/forward.h" }
diff --git a/libcxx/include/thread b/libcxx/include/thread
index bf751c8..a4632f6 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -88,7 +88,6 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
#include <__mutex_base>
#include <__thread/poll_with_backoff.h>
#include <__threading_support>
-#include <__utility/decay_copy.h>
#include <__utility/forward.h>
#include <chrono>
#include <cstddef>
@@ -303,8 +302,8 @@ thread::thread(_Fp&& __f, _Args&&... __args)
typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
unique_ptr<_Gp> __p(
new _Gp(_VSTD::move(__tsp),
- _VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
- _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
+ _VSTD::forward<_Fp>(__f),
+ _VSTD::forward<_Args>(__args)...));
int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
if (__ec == 0)
__p.release();
diff --git a/libcxx/include/utility b/libcxx/include/utility
index 9ab7b8e..9dd7905 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -218,6 +218,7 @@ template <class T>
#include <__debug>
#include <__tuple>
#include <__utility/as_const.h>
+#include <__utility/auto_cast.h>
#include <__utility/cmp.h>
#include <__utility/declval.h>
#include <__utility/exchange.h>
diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/utility/decay_copy.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/utility/auto_cast.module.verify.cpp
index b15d23c..cf012c3 100644
--- a/libcxx/test/libcxx/diagnostics/detail.headers/utility/decay_copy.module.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/detail.headers/utility/auto_cast.module.verify.cpp
@@ -11,5 +11,5 @@
// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.
-// expected-error@*:* {{use of private header from outside its module: '__utility/decay_copy.h'}}
-#include <__utility/decay_copy.h>
+// expected-error@*:* {{use of private header from outside its module: '__utility/auto_cast.h'}}
+#include <__utility/auto_cast.h>
diff --git a/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp b/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp
index 05e6211..95d2196 100644
--- a/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/range.access.begin/begin.pass.cpp
@@ -249,28 +249,27 @@ constexpr bool testBeginFunction() {
ASSERT_NOEXCEPT(std::ranges::begin(std::declval<int (&)[10]>()));
ASSERT_NOEXCEPT(std::ranges::cbegin(std::declval<int (&)[10]>()));
-template<class T>
struct NoThrowMemberBegin {
- T begin() const noexcept;
-};
-ASSERT_NOEXCEPT(std::ranges::begin(std::declval<NoThrowMemberBegin<int*>&>()));
-ASSERT_NOEXCEPT(std::ranges::cbegin(std::declval<NoThrowMemberBegin<int*>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::begin(std::declval<NoThrowMemberBegin<ThrowingIterator<int>>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::cbegin(std::declval<NoThrowMemberBegin<ThrowingIterator<int>>&>()));
+ ThrowingIterator<int> begin() const noexcept; // auto(t.begin()) doesn't throw
+} ntmb;
+static_assert(noexcept(std::ranges::begin(ntmb)));
+static_assert(noexcept(std::ranges::cbegin(ntmb)));
-template<class T>
struct NoThrowADLBegin {
- friend T begin(NoThrowADLBegin&) noexcept { return T{}; }
- friend T begin(NoThrowADLBegin const&) noexcept { return T{}; }
-};
-ASSERT_NOEXCEPT(std::ranges::begin(std::declval<NoThrowADLBegin<int*>&>()));
-ASSERT_NOEXCEPT(std::ranges::cbegin(std::declval<NoThrowADLBegin<int*>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::begin(std::declval<NoThrowADLBegin<ThrowingIterator<int>>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::cbegin(std::declval<NoThrowADLBegin<ThrowingIterator<int>>&>()));
+ friend ThrowingIterator<int> begin(NoThrowADLBegin&) noexcept; // auto(begin(t)) doesn't throw
+ friend ThrowingIterator<int> begin(const NoThrowADLBegin&) noexcept;
+} ntab;
+static_assert(noexcept(std::ranges::begin(ntab)));
+static_assert(noexcept(std::ranges::cbegin(ntab)));
+
+struct NoThrowMemberBeginReturnsRef {
+ ThrowingIterator<int>& begin() const noexcept; // auto(t.begin()) may throw
+} ntmbrr;
+static_assert(!noexcept(std::ranges::begin(ntmbrr)));
+static_assert(!noexcept(std::ranges::cbegin(ntmbrr)));
struct BeginReturnsArrayRef {
auto begin() const noexcept -> int(&)[10];
- auto end() const noexcept -> int(&)[10];
} brar;
static_assert(noexcept(std::ranges::begin(brar)));
static_assert(noexcept(std::ranges::cbegin(brar)));
diff --git a/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp b/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp
index 1e4fc02..84b4904 100644
--- a/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/range.access.end/end.pass.cpp
@@ -283,34 +283,34 @@ constexpr bool testEndFunction() {
ASSERT_NOEXCEPT(std::ranges::end(std::declval<int (&)[10]>()));
ASSERT_NOEXCEPT(std::ranges::cend(std::declval<int (&)[10]>()));
-template<class T>
struct NoThrowMemberEnd {
- T begin() const;
- T end() const noexcept;
-};
-ASSERT_NOEXCEPT(std::ranges::end(std::declval<NoThrowMemberEnd<int*>&>()));
-ASSERT_NOEXCEPT(std::ranges::cend(std::declval<NoThrowMemberEnd<int*>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::end(std::declval<NoThrowMemberEnd<ThrowingIterator<int>>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::cend(std::declval<NoThrowMemberEnd<ThrowingIterator<int>>&>()));
+ ThrowingIterator<int> begin() const;
+ ThrowingIterator<int> end() const noexcept; // auto(t.end()) doesn't throw
+} ntme;
+static_assert(noexcept(std::ranges::end(ntme)));
+static_assert(noexcept(std::ranges::cend(ntme)));
-template<class T>
struct NoThrowADLEnd {
- T begin() const;
- friend T end(NoThrowADLEnd&) noexcept { return T{}; }
- friend T end(NoThrowADLEnd const&) noexcept { return T{}; }
-};
-ASSERT_NOEXCEPT(std::ranges::end(std::declval<NoThrowADLEnd<int*>&>()));
-ASSERT_NOEXCEPT(std::ranges::cend(std::declval<NoThrowADLEnd<int*>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::end(std::declval<NoThrowADLEnd<ThrowingIterator<int>>&>()));
-ASSERT_NOT_NOEXCEPT(std::ranges::cend(std::declval<NoThrowADLEnd<ThrowingIterator<int>>&>()));
-
-struct BeginReturnsArrayRef {
+ ThrowingIterator<int> begin() const;
+ friend ThrowingIterator<int> end(NoThrowADLEnd&) noexcept; // auto(end(t)) doesn't throw
+ friend ThrowingIterator<int> end(const NoThrowADLEnd&) noexcept;
+} ntae;
+static_assert(noexcept(std::ranges::end(ntae)));
+static_assert(noexcept(std::ranges::cend(ntae)));
+
+struct NoThrowMemberEndReturnsRef {
+ ThrowingIterator<int> begin() const;
+ ThrowingIterator<int>& end() const noexcept; // auto(t.end()) may throw
+} ntmerr;
+static_assert(!noexcept(std::ranges::end(ntmerr)));
+static_assert(!noexcept(std::ranges::cend(ntmerr)));
+
+struct EndReturnsArrayRef {
auto begin() const noexcept -> int(&)[10];
auto end() const noexcept -> int(&)[10];
-} brar;
-static_assert(noexcept(std::ranges::end(brar)));
-static_assert(noexcept(std::ranges::cend(brar)));
-
+} erar;
+static_assert(noexcept(std::ranges::end(erar)));
+static_assert(noexcept(std::ranges::cend(erar)));
int main(int, char**) {
testArray();
diff --git a/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp b/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp
index 92023cc..4d91e3d 100644
--- a/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp
@@ -135,7 +135,7 @@ struct SizeFunctionSigned {
bool constexpr testHasSizeFunction() {
assert(std::ranges::size(SizeFunction()) == 42);
ASSERT_SAME_TYPE(decltype(std::ranges::size(SizeFunction())), size_t);
- assert(std::ranges::size(MoveOnlySizeFunction()) == 42);
+ static_assert(!std::is_invocable_v<RangeSizeT, MoveOnlySizeFunction>);
assert(std::ranges::size(EnumSizeFunction()) == 42);
assert(std::ranges::size(SizeFunctionConst()) == 42);
diff --git a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
index c0468fd..c3d5189 100644
--- a/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
+++ b/libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
@@ -21,7 +21,7 @@
// (It's fixed in the upcoming Clang 14, by https://reviews.llvm.org/D109651.)
// Prior to the fix, when statically linked, the unwind info for the two
// (default and overridden) operator new implementations clash.
-// XFAIL: target={{.+}}-windows-gnu && !windows-dll && clang-13
+// UNSUPPORTED: target={{.+}}-windows-gnu && !windows-dll && clang-13
#include <thread>
#include <new>