diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst index c571dd6f08fe9..4c4227dfef6a2 100644 --- a/libcxx/docs/ReleaseNotes/21.rst +++ b/libcxx/docs/ReleaseNotes/21.rst @@ -80,6 +80,9 @@ Deprecations and Removals - The ``_LIBCPP_VERBOSE_ABORT_NOT_NOEXCEPT`` has been removed, making ``std::__libcpp_verbose_abort`` unconditionally ``noexcept``. +- libc++ no longer adds ``constexpr`` to ``std::hash>::operator()``, as the ``constexpr`` addition + since C++20 was an unintended extension. + - TODO: The non-conforming extension ``packaged_task::result_type`` has been removed in LLVM 21. Potentially breaking changes diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h index a608ae522c561..e921e651e950f 100644 --- a/libcxx/include/__vector/vector_bool.h +++ b/libcxx/include/__vector/vector_bool.h @@ -512,7 +512,7 @@ class vector { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector&, false_type) _NOEXCEPT {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t __hash_code() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT; friend class __bit_reference; friend class __bit_const_reference; @@ -1093,7 +1093,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector::__invariants() cons } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 size_t vector::__hash_code() const _NOEXCEPT { +size_t vector::__hash_code() const _NOEXCEPT { size_t __h = 0; // do middle whole words size_type __n = __size_; @@ -1110,8 +1110,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t vector::__hash_code() con template struct hash > : public __unary_function, size_t> { - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t - operator()(const vector& __vec) const _NOEXCEPT { + _LIBCPP_HIDE_FROM_ABI size_t operator()(const vector& __vec) const _NOEXCEPT { return __vec.__hash_code(); } }; diff --git a/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp index 41cedd68fe50e..cba3101ef5009 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/enabled_hash.pass.cpp @@ -19,19 +19,14 @@ #include "test_macros.h" #include "min_allocator.h" -TEST_CONSTEXPR_CXX20 bool test() { +void test() { test_hash_enabled >(); test_hash_enabled>>(); - - return true; } int main(int, char**) { test_library_hash_specializations_available(); test(); -#if TEST_STD_VER > 17 - static_assert(test()); -#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp index e270869a8320f..670e934b5dddb 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/vector_bool.pass.cpp @@ -14,8 +14,6 @@ // size_t operator()(T val) const; // }; -// Not very portable - #include #include #include @@ -24,35 +22,29 @@ #include "test_macros.h" #include "min_allocator.h" -TEST_CONSTEXPR_CXX20 bool tests() { - { - typedef std::vector T; - typedef std::hash H; +template +TEST_CONSTEXPR_CXX20 void test() { + typedef std::hash H; #if TEST_STD_VER <= 14 - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); #endif - ASSERT_NOEXCEPT(H()(T())); - - bool ba[] = {true, false, true, true, false}; - T vb(std::begin(ba), std::end(ba)); - H h; - assert(h(vb) != 0); + ASSERT_NOEXCEPT(H()(VB())); + + bool ba[] = {true, false, true, true, false}; + VB vb(std::begin(ba), std::end(ba)); + H h; + if (!TEST_IS_CONSTANT_EVALUATED) { + const std::size_t hash_value = h(vb); + assert(h(vb) == hash_value); + LIBCPP_ASSERT(hash_value != 0); } +} + +TEST_CONSTEXPR_CXX20 bool tests() { + test >(); #if TEST_STD_VER >= 11 - { - typedef std::vector> T; - typedef std::hash H; -# if TEST_STD_VER <= 14 - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); -# endif - ASSERT_NOEXCEPT(H()(T())); - bool ba[] = {true, false, true, true, false}; - T vb(std::begin(ba), std::end(ba)); - H h; - assert(h(vb) != 0); - } + test>>(); #endif return true;