[libcxx-commits] [libcxx] [libc++][memory] LWG4148: `unique_ptr::operator*` should not allow dangling references (PR #214971)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Aug 8 23:46:34 PDT 2026
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/214971
>From c7a4c8e96a1b3e667a2c836892faa83e6e6dac68 Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Fri, 21 Feb 2025 20:13:33 +0200
Subject: [PATCH 1/9] [libcxx] implement LWG4148: unique_ptr::operator* should
not allow dangling references
---
libcxx/docs/Status/Cxx26Issues.csv | 2 +-
libcxx/include/__memory/unique_ptr.h | 8 ++++++
.../test/libcxx/memory/unique_ptr.verify.cpp | 27 +++++++++++++++++++
3 files changed, 36 insertions(+), 1 deletion(-)
create mode 100644 libcxx/test/libcxx/memory/unique_ptr.verify.cpp
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index db9bf85b72d4c..c30a7be48b86e 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -103,7 +103,7 @@
"`LWG4142 <https://wg21.link/LWG4142>`__","``format_parse_context::check_dynamic_spec`` should require at least one type","2024-11 (Wrocław)","","","`#118358 <https://github.com/llvm/llvm-project/issues/118358>`__",""
"`LWG4144 <https://wg21.link/LWG4144>`__","Disallow ``unique_ptr<T&, D>``","2024-11 (Wrocław)","|Complete|","23","`#118359 <https://github.com/llvm/llvm-project/issues/118359>`__",""
"`LWG4147 <https://wg21.link/LWG4147>`__","Precondition on ``inplace_vector::emplace``","2024-11 (Wrocław)","","","`#118361 <https://github.com/llvm/llvm-project/issues/118361>`__",""
-"`LWG4148 <https://wg21.link/LWG4148>`__","``unique_ptr::operator*`` should not allow dangling references","2024-11 (Wrocław)","","","`#118362 <https://github.com/llvm/llvm-project/issues/118362>`__",""
+"`LWG4148 <https://wg21.link/LWG4148>`__","``unique_ptr::operator*`` should not allow dangling references","2024-11 (Wrocław)","|Complete|","22","`#118362 <https://github.com/llvm/llvm-project/issues/118362>`__",""
"`LWG4153 <https://wg21.link/LWG4153>`__","Fix extra ""-1"" for ``philox_engine::max()``","2024-11 (Wrocław)","","","`#118363 <https://github.com/llvm/llvm-project/issues/118363>`__",""
"`LWG4154 <https://wg21.link/LWG4154>`__","The Mandates for ``std::packaged_task``'s constructor from a callable entity should consider decaying","2024-11 (Wrocław)","","","`#118364 <https://github.com/llvm/llvm-project/issues/118364>`__",""
"`LWG4157 <https://wg21.link/LWG4157>`__","The resolution of LWG3465 was damaged by P2167R3","2024-11 (Wrocław)","|Complete|","20","`#118365 <https://github.com/llvm/llvm-project/issues/118365>`__",""
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index fcae9d84eb991..62d43bea9613d 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -237,6 +237,14 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
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>())) {
+ // TODO(LLVM-21): Remove this workaround
+#if __has_builtin(__reference_converts_from_temporary) || \
+ (defined(_LIBCPP_CLANG_VER) && \
+ ((!defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 1901) || (defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 2000)))
+ static_assert(
+ !__reference_converts_from_temporary(__add_lvalue_reference_t<_Tp>, decltype(*std::declval<pointer>())),
+ "Reference type _Tp must not convert from a temporary object");
+#endif
return *__ptr_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
diff --git a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
new file mode 100644
index 0000000000000..6bd3d8818431f
--- /dev/null
+++ b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++11
+
+// <memory>
+
+#include <memory>
+
+struct deleter {
+ using pointer = long*;
+ void operator()(pointer) const {}
+};
+
+int main(int, char**) {
+ long l = 0;
+ std::unique_ptr<const int, deleter> p(&l);
+ // expected-error-re@*:* {{static assertion failed{{.*}}'!__reference_converts_from_temporary(const int &, long &)': Reference type _Tp must not convert from a temporary object}}
+ // expected-error@*:*{{returning reference to local temporary object}}
+ int i = *p; // expected-note {{requested here}}
+ return 0;
+}
>From c3297df460b0a7419abc427431adddeb7e85891c Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Wed, 6 May 2026 01:29:54 +0300
Subject: [PATCH 2/9] Address comments
---
libcxx/include/__memory/unique_ptr.h | 8 ++------
libcxx/test/libcxx/memory/unique_ptr.verify.cpp | 5 ++---
2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 62d43bea9613d..ff756d010a866 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -42,6 +42,7 @@
#include <__type_traits/is_trivially_relocatable.h>
#include <__type_traits/is_void.h>
#include <__type_traits/nat.h>
+#include <__type_traits/reference_converts_from_temporary.h>
#include <__type_traits/remove_extent.h>
#include <__type_traits/remove_reference.h>
#include <__type_traits/void_t.h>
@@ -237,14 +238,9 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
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>())) {
- // TODO(LLVM-21): Remove this workaround
-#if __has_builtin(__reference_converts_from_temporary) || \
- (defined(_LIBCPP_CLANG_VER) && \
- ((!defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 1901) || (defined(__ANDROID__) && _LIBCPP_CLANG_VER >= 2000)))
static_assert(
- !__reference_converts_from_temporary(__add_lvalue_reference_t<_Tp>, decltype(*std::declval<pointer>())),
+ !__reference_converts_from_temporary_v<__add_lvalue_reference_t<_Tp>, decltype(*std::declval<pointer>())>,
"Reference type _Tp must not convert from a temporary object");
-#endif
return *__ptr_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
diff --git a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
index 6bd3d8818431f..e9c36a643e91f 100644
--- a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
+++ b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
@@ -17,11 +17,10 @@ struct deleter {
void operator()(pointer) const {}
};
-int main(int, char**) {
+void test() {
long l = 0;
std::unique_ptr<const int, deleter> p(&l);
// expected-error-re@*:* {{static assertion failed{{.*}}'!__reference_converts_from_temporary(const int &, long &)': Reference type _Tp must not convert from a temporary object}}
// expected-error@*:*{{returning reference to local temporary object}}
- int i = *p; // expected-note {{requested here}}
- return 0;
+ std::ignore = *p; // expected-note {{requested here}}
}
>From d01d32cbd363ddfd83fa14fe758e5f2a2e97300c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Sat, 8 Aug 2026 16:35:40 +0300
Subject: [PATCH 3/9] Apply suggestions from code review
Co-authored-by: A. Jiang <de34 at live.cn>
---
libcxx/docs/Status/Cxx26Issues.csv | 2 +-
libcxx/include/__memory/unique_ptr.h | 2 +-
libcxx/test/libcxx/memory/unique_ptr.verify.cpp | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index c30a7be48b86e..1361aaa316178 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -103,7 +103,7 @@
"`LWG4142 <https://wg21.link/LWG4142>`__","``format_parse_context::check_dynamic_spec`` should require at least one type","2024-11 (Wrocław)","","","`#118358 <https://github.com/llvm/llvm-project/issues/118358>`__",""
"`LWG4144 <https://wg21.link/LWG4144>`__","Disallow ``unique_ptr<T&, D>``","2024-11 (Wrocław)","|Complete|","23","`#118359 <https://github.com/llvm/llvm-project/issues/118359>`__",""
"`LWG4147 <https://wg21.link/LWG4147>`__","Precondition on ``inplace_vector::emplace``","2024-11 (Wrocław)","","","`#118361 <https://github.com/llvm/llvm-project/issues/118361>`__",""
-"`LWG4148 <https://wg21.link/LWG4148>`__","``unique_ptr::operator*`` should not allow dangling references","2024-11 (Wrocław)","|Complete|","22","`#118362 <https://github.com/llvm/llvm-project/issues/118362>`__",""
+"`LWG4148 <https://wg21.link/LWG4148>`__","``unique_ptr::operator*`` should not allow dangling references","2024-11 (Wrocław)","|Complete|","24","`#118362 <https://github.com/llvm/llvm-project/issues/118362>`__",""
"`LWG4153 <https://wg21.link/LWG4153>`__","Fix extra ""-1"" for ``philox_engine::max()``","2024-11 (Wrocław)","","","`#118363 <https://github.com/llvm/llvm-project/issues/118363>`__",""
"`LWG4154 <https://wg21.link/LWG4154>`__","The Mandates for ``std::packaged_task``'s constructor from a callable entity should consider decaying","2024-11 (Wrocław)","","","`#118364 <https://github.com/llvm/llvm-project/issues/118364>`__",""
"`LWG4157 <https://wg21.link/LWG4157>`__","The resolution of LWG3465 was damaged by P2167R3","2024-11 (Wrocław)","|Complete|","20","`#118365 <https://github.com/llvm/llvm-project/issues/118365>`__",""
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index ff756d010a866..8c2959db8c464 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -240,7 +240,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
_NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
static_assert(
!__reference_converts_from_temporary_v<__add_lvalue_reference_t<_Tp>, decltype(*std::declval<pointer>())>,
- "Reference type _Tp must not convert from a temporary object");
+ "the returned reference must not bind to a temporary object");
return *__ptr_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
diff --git a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
index e9c36a643e91f..7f6541c101ddd 100644
--- a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
+++ b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
@@ -20,7 +20,7 @@ struct deleter {
void test() {
long l = 0;
std::unique_ptr<const int, deleter> p(&l);
- // expected-error-re@*:* {{static assertion failed{{.*}}'!__reference_converts_from_temporary(const int &, long &)': Reference type _Tp must not convert from a temporary object}}
- // expected-error@*:*{{returning reference to local temporary object}}
- std::ignore = *p; // expected-note {{requested here}}
+// expected-error-re@*:* {{static assertion failed{{.*}}the returned reference must not bind to a temporary object}}
+ // expected-error@*:* 0-1{{returning reference to local temporary object}}
+ (void)*p; // expected-note {{requested here}}
}
>From 88fbe1bcb01b9dc64d6035ac658d4118004c023b Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 8 Aug 2026 17:45:36 +0300
Subject: [PATCH 4/9] [libc++][memory] LWG4148: `unique_ptr::operator*` should
not allow dangling references
Implements: https://wg21.link/LWG4148
Closes https://github.com/llvm/llvm-project/issues/118362
---
libcxx/include/__memory/unique_ptr.h | 2 +-
.../reference_converts_from_temporary.h | 11 +++++++----
libcxx/test/libcxx/memory/unique_ptr.verify.cpp | 16 +++++++++++-----
3 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 8c2959db8c464..c8392d35c352f 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -240,7 +240,7 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
_NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
static_assert(
!__reference_converts_from_temporary_v<__add_lvalue_reference_t<_Tp>, decltype(*std::declval<pointer>())>,
- "the returned reference must not bind to a temporary object");
+ "The returned reference must not bind to a temporary object.");
return *__ptr_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
diff --git a/libcxx/include/__type_traits/reference_converts_from_temporary.h b/libcxx/include/__type_traits/reference_converts_from_temporary.h
index 31479e43ee2c4..d9eeb88a5758f 100644
--- a/libcxx/include/__type_traits/reference_converts_from_temporary.h
+++ b/libcxx/include/__type_traits/reference_converts_from_temporary.h
@@ -15,10 +15,13 @@
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER >= 23
+template <class _Tp, class _Up>
+inline const bool __reference_converts_from_temporary_v = __reference_converts_from_temporary(_Tp, _Up);
-_LIBCPP_BEGIN_NAMESPACE_STD
+#if _LIBCPP_STD_VER >= 23
template <class _Tp, class _Up>
struct _LIBCPP_NO_SPECIALIZATIONS reference_converts_from_temporary
@@ -28,8 +31,8 @@ template <class _Tp, class _Up>
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool reference_converts_from_temporary_v =
__reference_converts_from_temporary(_Tp, _Up);
-_LIBCPP_END_NAMESPACE_STD
-
#endif // _LIBCPP_STD_VER >= 23
+_LIBCPP_END_NAMESPACE_STD
+
#endif // _LIBCPP___TYPE_TRAITS_REFERENCE_CONVERTS_FROM_TEMPORARY_H
diff --git a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
index 7f6541c101ddd..e0305e80443bb 100644
--- a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
+++ b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
@@ -12,15 +12,21 @@
#include <memory>
-struct deleter {
+#include "test_macros.h"
+
+struct Deleter {
using pointer = long*;
+
void operator()(pointer) const {}
};
void test() {
long l = 0;
- std::unique_ptr<const int, deleter> p(&l);
-// expected-error-re@*:* {{static assertion failed{{.*}}the returned reference must not bind to a temporary object}}
- // expected-error@*:* 0-1{{returning reference to local temporary object}}
- (void)*p; // expected-note {{requested here}}
+ std::unique_ptr<const int, Deleter> p{&l};
+
+// expected-error-re@*:* {{static assertion failed due to requirement {{.+}}The returned reference must not bind to a temporary object.}}
+#if TEST_STD_VER >= 26
+// expected-error@*:* {{returning reference to local temporary object}}
+#endif
+ [[maybe_unused]] int i = *p;
}
>From 3d35b0813b2faaf685e1ab60e470a24d49b83773 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 8 Aug 2026 17:49:15 +0300
Subject: [PATCH 5/9] Formatting
---
.../include/__type_traits/reference_converts_from_temporary.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/include/__type_traits/reference_converts_from_temporary.h b/libcxx/include/__type_traits/reference_converts_from_temporary.h
index d9eeb88a5758f..8d879e436cab8 100644
--- a/libcxx/include/__type_traits/reference_converts_from_temporary.h
+++ b/libcxx/include/__type_traits/reference_converts_from_temporary.h
@@ -15,7 +15,7 @@
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
-
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp, class _Up>
>From 43ab97c5f60f730d955e134bac51d28d4c79968c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 8 Aug 2026 21:37:11 +0300
Subject: [PATCH 6/9] Addressed a review comment
---
.../test/libcxx/memory/unique_ptr.verify.cpp | 32 -------------------
.../dereference.verify.cpp | 25 +++++++++++++--
2 files changed, 22 insertions(+), 35 deletions(-)
delete mode 100644 libcxx/test/libcxx/memory/unique_ptr.verify.cpp
diff --git a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp b/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
deleted file mode 100644
index e0305e80443bb..0000000000000
--- a/libcxx/test/libcxx/memory/unique_ptr.verify.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// REQUIRES: std-at-least-c++11
-
-// <memory>
-
-#include <memory>
-
-#include "test_macros.h"
-
-struct Deleter {
- using pointer = long*;
-
- void operator()(pointer) const {}
-};
-
-void test() {
- long l = 0;
- std::unique_ptr<const int, Deleter> p{&l};
-
-// expected-error-re@*:* {{static assertion failed due to requirement {{.+}}The returned reference must not bind to a temporary object.}}
-#if TEST_STD_VER >= 26
-// expected-error@*:* {{returning reference to local temporary object}}
-#endif
- [[maybe_unused]] int i = *p;
-}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
index 46506e5622622..9610b1b7e5b98 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
@@ -16,9 +16,28 @@
#include "test_macros.h"
-void f() {
+void test {
std::unique_ptr<int[]> p(new int(3));
const std::unique_ptr<int[]>& cp = p;
- TEST_IGNORE_NODISCARD(*p); // expected-error-re {{indirection requires pointer operand ('std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
- TEST_IGNORE_NODISCARD(*cp); // expected-error-re {{indirection requires pointer operand ('const std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
+ TEST_IGNORE_NODISCARD(
+ *p); // expected-error-re {{indirection requires pointer operand ('std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
+ TEST_IGNORE_NODISCARD(
+ *cp); // expected-error-re {{indirection requires pointer operand ('const std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
+}
+
+void test_lwg4196 {
+ struct Deleter {
+ using pointer = long*;
+
+ void operator()(pointer) const {}
+ };
+
+ long l = 0;
+ std::unique_ptr<const int, Deleter> p{&l};
+
+ // expected-error-re@*:* {{static assertion failed due to requirement {{.+}}The returned reference must not bind to a temporary object.}}
+#if TEST_STD_VER >= 26
+ // expected-error@*:* {{returning reference to local temporary object}}
+#endif
+ [[maybe_unused]] int i = *p;
}
>From 0a0377ab324f0c8da485a10f58a2f9f3ad14f75a Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 8 Aug 2026 21:44:15 +0300
Subject: [PATCH 7/9] Fixes
---
.../unique.ptr.observers/dereference.verify.cpp | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
index 9610b1b7e5b98..7902448f56f75 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
@@ -16,16 +16,17 @@
#include "test_macros.h"
-void test {
+void test() {
std::unique_ptr<int[]> p(new int(3));
const std::unique_ptr<int[]>& cp = p;
- TEST_IGNORE_NODISCARD(
- *p); // expected-error-re {{indirection requires pointer operand ('std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
- TEST_IGNORE_NODISCARD(
- *cp); // expected-error-re {{indirection requires pointer operand ('const std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
+
+ // expected-error-re at +1 {{indirection requires pointer operand ('std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
+ TEST_IGNORE_NODISCARD(*p);
+ // expected-error-re at +1 {{indirection requires pointer operand ('const std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
+ TEST_IGNORE_NODISCARD(*cp);
}
-void test_lwg4196 {
+void test_lwg4196() {
struct Deleter {
using pointer = long*;
@@ -33,7 +34,7 @@ void test_lwg4196 {
};
long l = 0;
- std::unique_ptr<const int, Deleter> p{&l};
+ std::unique_ptr<const int, Deleter> p(&l);
// expected-error-re@*:* {{static assertion failed due to requirement {{.+}}The returned reference must not bind to a temporary object.}}
#if TEST_STD_VER >= 26
>From e965d6f2ef4c6cde732b9640e72c7dc78e7b0296 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 8 Aug 2026 21:55:31 +0300
Subject: [PATCH 8/9] Revert some
---
.../unique.ptr.observers/dereference.verify.cpp | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
index 7902448f56f75..da00f42697425 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
@@ -19,11 +19,8 @@
void test() {
std::unique_ptr<int[]> p(new int(3));
const std::unique_ptr<int[]>& cp = p;
-
- // expected-error-re at +1 {{indirection requires pointer operand ('std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
- TEST_IGNORE_NODISCARD(*p);
- // expected-error-re at +1 {{indirection requires pointer operand ('const std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
- TEST_IGNORE_NODISCARD(*cp);
+ TEST_IGNORE_NODISCARD(*p); // expected-error-re {{indirection requires pointer operand ('std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
+ TEST_IGNORE_NODISCARD(*cp); // expected-error-re {{indirection requires pointer operand ('const std::unique_ptr<int{{[ ]*}}[]>' invalid)}}
}
void test_lwg4196() {
>From d87a50ea948eaa28240c6e35dbd1cb16684654eb Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 9 Aug 2026 09:46:11 +0300
Subject: [PATCH 9/9] Frozen headers fix
---
.../unique.ptr.observers/dereference.verify.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
index da00f42697425..7137e748de460 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.verify.cpp
@@ -12,6 +12,8 @@
// test op*()
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
#include <memory>
#include "test_macros.h"
More information about the libcxx-commits
mailing list