[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