[libcxx-commits] [libcxx] [libc++] LWG4324: `unique_ptr<void>::operator*` is not SFINAE-friendly (PR #190919)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Apr 8 00:02:07 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

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

<details>
<summary>Changes</summary>

Fixes #<!-- -->189825.

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


3 Files Affected:

- (modified) libcxx/docs/Status/Cxx2cIssues.csv (+1-1) 
- (modified) libcxx/include/__memory/unique_ptr.h (+7) 
- (modified) libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp (+11) 


``````````diff
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 75972e0b2874c..94584349e7282 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -280,7 +280,7 @@
 "`LWG4259 <https://wg21.link/LWG4259>`__","P1148R0 changed the return values of searching functions of ``std::basic_string`` on some platforms","2026-03 (Croydon)","","","`#189822 <https://github.com/llvm/llvm-project/issues/189822>`__",""
 "`LWG4290 <https://wg21.link/LWG4290>`__","Missing *Mandates* clauses on ``is_sufficiently_aligned``","2026-03 (Croydon)","","","`#189823 <https://github.com/llvm/llvm-project/issues/189823>`__",""
 "`LWG4314 <https://wg21.link/LWG4314>`__","Missing move in ``mdspan`` layout ``mapping::operator()``","2026-03 (Croydon)","","","`#189824 <https://github.com/llvm/llvm-project/issues/189824>`__",""
-"`LWG4324 <https://wg21.link/LWG4324>`__","``unique_ptr<void>::operator*`` is not SFINAE-friendly","2026-03 (Croydon)","","","`#189825 <https://github.com/llvm/llvm-project/issues/189825>`__",""
+"`LWG4324 <https://wg21.link/LWG4324>`__","``unique_ptr<void>::operator*`` is not SFINAE-friendly","2026-03 (Croydon)","|Complete|","23","`#189825 <https://github.com/llvm/llvm-project/issues/189825>`__",""
 "`LWG4325 <https://wg21.link/LWG4325>`__","``std::indirect``'s ``operator==`` still does not support incomplete types","2026-03 (Croydon)","","","`#189826 <https://github.com/llvm/llvm-project/issues/189826>`__",""
 "`LWG4339 <https://wg21.link/LWG4339>`__","``task``'s coroutine frame may be released late","2026-03 (Croydon)","","","`#189827 <https://github.com/llvm/llvm-project/issues/189827>`__",""
 "`LWG4347 <https://wg21.link/LWG4347>`__","``task``'s stop source is always created","2026-03 (Croydon)","","","`#189828 <https://github.com/llvm/llvm-project/issues/189828>`__",""
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 6a4ec0a466ba7..8fba2a4a1509d 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -117,6 +117,12 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> {
   typedef false_type __enable_rval_overload;
 };
 
+template <class, class = void>
+inline const bool __can_dereference = false;
+
+template <class _Tp>
+inline const bool __can_dereference<_Tp, decltype((void)*std::declval<_Tp>())> = true;
+
 #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
 #  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
 #else
@@ -258,6 +264,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
     return *this;
   }
 
+  template <class _Ptr = pointer, __enable_if_t<__can_dereference<_Ptr>, int> = 0>
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
       _NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
     return *__ptr_;
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
index 4063190838a27..c91b6358e68bc 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
@@ -16,6 +16,7 @@
 #include <memory>
 #include <utility>
 #include <vector>
+#include <type_traits>
 
 #include "test_macros.h"
 
@@ -31,6 +32,16 @@ struct Deleter {
 };
 #endif
 
+template<class, class = void>
+struct can_dereference : std::false_type {};
+template<class T>
+struct can_dereference<T, decltype((void)*std::declval<T>())> : std::true_type {};
+
+static_assert(can_dereference<std::unique_ptr<int> >::value, "");
+static_assert(can_dereference<const std::unique_ptr<int>&>::value, "");
+static_assert(!can_dereference<std::unique_ptr<void> >::value, "");
+static_assert(!can_dereference<const std::unique_ptr<void>&>::value, "");
+
 TEST_CONSTEXPR_CXX23 bool test() {
   {
     std::unique_ptr<int> p(new int(3));

``````````

</details>


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


More information about the libcxx-commits mailing list