[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