diff --git a/stl/inc/xutility b/stl/inc/xutility index c38cab33263..5805b9012a6 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -866,8 +866,36 @@ namespace ranges { template concept _Can_deref = requires(_Ty&& __t) { *static_cast<_Ty&&>(__t); }; + struct _Must_have_ADL_found_iter_move_or_be_dereferenceable {}; + class _Cpo { private: + template + _NODISCARD static auto _Choose_return_type() { + if constexpr (_Has_ADL<_Ty>) { + return type_identity()))>{}; // intentional ADL + } else if constexpr (_Can_deref<_Ty>) { + using _Ref = decltype(*_STD declval<_Ty>()); +#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-1008447, VSO-2066340 + if constexpr (is_function_v>) { + return type_identity<_Ref&>{}; + } else +#endif // ^^^ workaround ^^^ + { + if constexpr (is_lvalue_reference_v<_Ref>) { + return type_identity&&>{}; + } else { + return type_identity<_Ref>{}; + } + } + } else { + return _Must_have_ADL_found_iter_move_or_be_dereferenceable{}; + } + } + + template + using _Return_type = decltype(_Choose_return_type<_Ty>())::type; + enum class _St { _None, _Custom, _Fallback }; template @@ -886,8 +914,7 @@ namespace ranges { public: template - requires (_Choice<_Ty>._Strategy != _St::_None) - _NODISCARD _STATIC_CALL_OPERATOR constexpr decltype(auto) operator()(_Ty&& _Val) _CONST_CALL_OPERATOR + _NODISCARD _STATIC_CALL_OPERATOR constexpr _Return_type<_Ty> operator()(_Ty&& _Val) _CONST_CALL_OPERATOR noexcept(_Choice<_Ty>._No_throw) { constexpr _St _Strat = _Choice<_Ty>._Strategy; @@ -1121,8 +1148,8 @@ struct _Projected_impl { using value_type = remove_cvref_t>; [[noreturn]] indirect_result_t<_Proj&, _It> operator*() const { - _STL_REPORT_ERROR("std::projected::operator*() can't be called (N5008 [projected]/1)"); - _STL_UNREACHABLE; // no return value available for "continue on error" + static_assert( + false, "std::projected::operator*() can't be instantiated (N5008 [projected] as modified by LWG-4270)"); } }; }; diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 984f683b573..0e91de44821 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -1164,12 +1164,6 @@ std/containers/sequences/vector.bool/vector_bool.pass.cpp FAIL # Not analyzed. Inspecting shift operators for quoted(). std/input.output/iostream.format/quoted.manip/quoted_traits.compile.pass.cpp FAIL -# Not analyzed. -# MSVC warning C5046: 'test_undefined_internal::A::operator *': Symbol involving type with internal linkage not defined -# Clang error: function 'test_undefined_internal()::A::operator*' has internal linkage but is not defined [-Werror,-Wundefined-internal] -std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp FAIL -std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.comp/op_spaceship.pass.cpp FAIL - # Not analyzed. Failing assert(arr[0].moves() == 1 && arr[1].moves() == 3). std/iterators/iterator.requirements/iterator.cust/iterator.cust.swap/iter_swap.pass.cpp FAIL @@ -1518,9 +1512,6 @@ std/algorithms/alg.sorting/alg.set.operations/set.intersection/set_intersection_ # Clang assertion: std::hermite(n, +inf) == inf std/numerics/c.math/hermite.pass.cpp FAIL -# Not analyzed. Test coverage for LLVM-104496 uses span. -std/containers/views/views.span/span.cons/copy.pass.cpp FAIL - # Not analyzed. These tests disable or limit allocations, which interferes with our proxy objects. std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp FAIL std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp FAIL diff --git a/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp index 9b09228e279..aa4834cdeb3 100644 --- a/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp +++ b/tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp @@ -1073,9 +1073,7 @@ namespace iterator_cust_move_test { static_assert(noexcept(ranges::iter_move(static_cast(&some_ints[2])))); static_assert(same_as, int&&>); -#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-1008447, VSO-2066340 static_assert(same_as, int (&)(int)>); -#endif // ^^^ no workaround ^^^ static_assert(same_as, int&&>); static_assert(ranges::iter_move(some_ints) == 0); @@ -1084,9 +1082,7 @@ namespace iterator_cust_move_test { constexpr int f(int i) noexcept { return i + 1; } -#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-1008447 static_assert(same_as, int (&)(int)>); -#endif // ^^^ no workaround ^^^ static_assert(ranges::iter_move(&f)(42) == 43); static_assert(noexcept(ranges::iter_move(&f)));