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

via libcxx-commits libcxx-commits at lists.llvm.org
Sat May 9 08:53:31 PDT 2026


Author: A. Jiang
Date: 2026-05-09T23:53:26+08:00
New Revision: 2caea408ab90333d86efc857a3924315f3bc90ab

URL: https://github.com/llvm/llvm-project/commit/2caea408ab90333d86efc857a3924315f3bc90ab
DIFF: https://github.com/llvm/llvm-project/commit/2caea408ab90333d86efc857a3924315f3bc90ab.diff

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

---------

Co-authored-by: Hristo Hristov <zingam at outlook.com>

Added: 
    

Modified: 
    libcxx/docs/Status/Cxx2cIssues.csv
    libcxx/include/__memory/unique_ptr.h
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index c875f75528894..42ab96ef5657a 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..b9d8a1b563b6c 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
@@ -12,8 +12,11 @@
 
 // test op*()
 
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
 #include <cassert>
 #include <memory>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
@@ -31,6 +34,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));


        


More information about the libcxx-commits mailing list