[libcxx-commits] [libcxx] [libc++] Treat P0513R0 as a defect report against C++11 (PR #166690)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Nov 5 18:59:19 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

<details>
<summary>Changes</summary>

P0513R0 is essentially a collective resolution paper of LWG2543, LWG2791, LWG2809, and LWG2817.

Among these LWG issues, LWG2543 (conditionally enabled `hash`) and LWG2817 (`hash<nullptr_t>`) affect pre-C++17 utilities. We generally backport changes from LWG issues, so this patch backports the relavent parts of P0513R0.

Although we provide `hash<unique_ptr>` as an extension in C++03 mode, as C++03 mode isn't encouraged now, this patch leaves `hash<unique_ptr>` unchanged in C++03 mode.

Fixes #<!-- -->136800.

---
Full diff: https://github.com/llvm/llvm-project/pull/166690.diff


5 Files Affected:

- (modified) libcxx/docs/Status/Cxx17Papers.csv (+1-1) 
- (modified) libcxx/include/__functional/hash.h (-9) 
- (modified) libcxx/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp (+6-10) 
- (modified) libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp (-2) 
- (modified) libcxx/test/support/poisoned_hash_helper.h (+3-7) 


``````````diff
diff --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv
index 1a9d3b08f3ec3..6bb29823d1b9b 100644
--- a/libcxx/docs/Status/Cxx17Papers.csv
+++ b/libcxx/docs/Status/Cxx17Papers.csv
@@ -84,7 +84,7 @@
 "`P0508R0 <https://wg21.link/P0508R0>`__","Wording for GB 58 - structured bindings for node_handles","2016-11 (Issaquah)","|Complete|","7","`#99944 <https://github.com/llvm/llvm-project/issues/99944>`__",""
 "`P0509R1 <https://wg21.link/P0509R1>`__","Updating ""Restrictions on exception handling""","2016-11 (Issaquah)","|Nothing To Do|","n/a","`#103676 <https://github.com/llvm/llvm-project/issues/103676>`__",""
 "`P0510R0 <https://wg21.link/P0510R0>`__","Disallowing references, incomplete types, arrays, and empty variants","2016-11 (Issaquah)","|Complete|","4","`#103677 <https://github.com/llvm/llvm-project/issues/103677>`__",""
-"`P0513R0 <https://wg21.link/P0513R0>`__","Poisoning the Hash","2016-11 (Issaquah)","|Complete|","5","`#103678 <https://github.com/llvm/llvm-project/issues/103678>`__",""
+"`P0513R0 <https://wg21.link/P0513R0>`__","Poisoning the Hash","2016-11 (Issaquah)","|Complete|","5","`#103678 <https://github.com/llvm/llvm-project/issues/103678>`__","Implemented as a DR against C++11 since LLVM 22. MSVC STL does the same."
 "`P0516R0 <https://wg21.link/P0516R0>`__","Clarify That shared_future's Copy Operations have Wide Contracts","2016-11 (Issaquah)","|Complete|","4","`#103679 <https://github.com/llvm/llvm-project/issues/103679>`__",""
 "`P0517R0 <https://wg21.link/P0517R0>`__","Make future_error Constructible","2016-11 (Issaquah)","|Complete|","4","`#103680 <https://github.com/llvm/llvm-project/issues/103680>`__",""
 "`P0521R0 <https://wg21.link/P0521R0>`__","Proposed Resolution for CA 14 (shared_ptr use_count/unique)","2016-11 (Issaquah)","|Complete|","18","`#103681 <https://github.com/llvm/llvm-project/issues/103681>`__",""
diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h
index 83bbf1b5e26c3..f74f25fa6e84b 100644
--- a/libcxx/include/__functional/hash.h
+++ b/libcxx/include/__functional/hash.h
@@ -433,13 +433,10 @@ struct __hash_impl<long double> : __scalar_hash<long double> {
 template <class _Tp>
 struct hash : public __hash_impl<_Tp> {};
 
-#if _LIBCPP_STD_VER >= 17
-
 template <>
 struct hash<nullptr_t> : public __unary_function<nullptr_t, size_t> {
   _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; }
 };
-#endif
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Key, class _Hash>
@@ -452,18 +449,12 @@ template <class _Key, class _Hash = hash<_Key> >
 using __has_enabled_hash _LIBCPP_NODEBUG =
     integral_constant<bool, __check_hash_requirements<_Key, _Hash>::value && is_default_constructible<_Hash>::value >;
 
-#  if _LIBCPP_STD_VER >= 17
 template <class _Type, class>
 using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type;
 
 template <class _Type, class... _Keys>
 using __enable_hash_helper _LIBCPP_NODEBUG =
     __enable_hash_helper_imp<_Type, __enable_if_t<__all<__has_enabled_hash<_Keys>::value...>::value> >;
-#  else
-template <class _Type, class...>
-using __enable_hash_helper _LIBCPP_NODEBUG = _Type;
-#  endif
-
 #endif // !_LIBCPP_CXX03_LANG
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp b/libcxx/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp
index 448c5ba143c10..784831018a006 100644
--- a/libcxx/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp
@@ -44,18 +44,14 @@ test()
     assert(h(&i) != h(&j));
 }
 
-// can't hash nullptr_t until C++17
-void test_nullptr()
-{
-#if TEST_STD_VER > 14
-    typedef std::nullptr_t T;
-    typedef std::hash<T> H;
+void test_nullptr() {
+  typedef std::nullptr_t T;
+  typedef std::hash<T> H;
 #if TEST_STD_VER <= 17
-    static_assert((std::is_same<typename H::argument_type, T>::value), "" );
-    static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
-#endif
-    ASSERT_NOEXCEPT(H()(T()));
+  static_assert((std::is_same<typename H::argument_type, T>::value), "");
+  static_assert((std::is_same<typename H::result_type, std::size_t>::value), "");
 #endif
+  ASSERT_NOEXCEPT(H()(T()));
 }
 
 int main(int, char**)
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
index 32fc949354c69..e7540498b8de7 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
@@ -90,12 +90,10 @@ int main(int, char**)
     test_enabled_with_deleter<A, PointerDeleter<A, 1>>();
     test_enabled_with_deleter<A[], PointerDeleter<A[], 1>>();
 
-#if TEST_STD_VER > 14
     test_disabled_with_deleter<int, PointerDeleter<int, 0>>();
     test_disabled_with_deleter<int[], PointerDeleter<int[], 0>>();
     test_disabled_with_deleter<A, PointerDeleter<A, 0>>();
     test_disabled_with_deleter<A[], PointerDeleter<A[], 0>>();
-#endif
   }
 #endif
 
diff --git a/libcxx/test/support/poisoned_hash_helper.h b/libcxx/test/support/poisoned_hash_helper.h
index 93b579d2dfde3..cd71cd70d6a84 100644
--- a/libcxx/test/support/poisoned_hash_helper.h
+++ b/libcxx/test/support/poisoned_hash_helper.h
@@ -123,13 +123,9 @@ struct Class {};
 // Each header that declares the std::hash template provides enabled
 // specializations of std::hash for std::nullptr_t and all cv-unqualified
 // arithmetic, enumeration, and pointer types.
-#if TEST_STD_VER >= 17
-using MaybeNullptr = types::type_list<std::nullptr_t>;
-#else
-using MaybeNullptr = types::type_list<>;
-#endif
-using LibraryHashTypes = types::
-    concatenate_t<types::arithmetic_types, types::type_list<Enum, EnumClass, void*, void const*, Class*>, MaybeNullptr>;
+using LibraryHashTypes =
+    types::concatenate_t<types::arithmetic_types,
+                         types::type_list<Enum, EnumClass, void*, void const*, Class*, std::nullptr_t>>;
 
 struct TestHashEnabled {
   template <class T>

``````````

</details>


https://github.com/llvm/llvm-project/pull/166690


More information about the libcxx-commits mailing list