[libcxx-commits] [libcxx] [libc++][memory] Applied `[[nodiscard]]` to smart pointers (PR #168483)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Nov 18 10:08:49 PST 2025
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/168483
>From 207b44f595ad590a4d85e67b1bc498acf7f08cfa Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 17 Nov 2025 13:13:44 +0200
Subject: [PATCH 1/5] [libc++][memory] Applied `[[nodiscard]]` to smart
pointers
Applied `[[nodiscard]]` where relevant to smart pointers and related functions.
See guidelines:
- https://libcxx.llvm.org/CodingGuidelines.html#apply-nodiscard-where-relevant
- `[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue. For example a locking constructor in unique_lock.
---
libcxx/include/__memory/shared_ptr.h | 100 +++++++------
libcxx/include/__memory/unique_ptr.h | 25 ++--
.../utilities/smartptr/nodiscard.verify.cpp | 134 +++++++++++++++++-
3 files changed, 204 insertions(+), 55 deletions(-)
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index ee07efe081e51..a470c673425fa 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -568,16 +568,20 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
shared_ptr(__p, __d, __a).swap(*this);
}
- _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
- _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { return *__ptr_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT {
+ return *__ptr_;
+ }
_LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT {
static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
return __ptr_;
}
- _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
+ return __cntrl_ ? __cntrl_->use_count() : 0;
+ }
#if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; }
@@ -586,19 +590,19 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; }
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
return __cntrl_ < __p.__cntrl_;
}
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
return __cntrl_ < __p.__cntrl_;
}
_LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }
#if _LIBCPP_STD_VER >= 17
- _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
return __ptr_[__i];
}
@@ -669,7 +673,7 @@ shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
// std::allocate_shared and std::make_shared
//
template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
__allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
@@ -680,21 +684,21 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&
}
template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...);
}
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
_ForOverwriteAllocator __alloc(__a);
return std::allocate_shared<_Tp>(__alloc);
}
template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
return std::allocate_shared_for_overwrite<_Tp>(allocator<__remove_cv_t<_Tp>>());
}
@@ -886,67 +890,69 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _
// bounded array variants
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
return std::__allocate_shared_bounded_array<_Tp>(__a);
}
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
}
template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
_ForOverwriteAllocator __alloc(__a);
return std::__allocate_shared_bounded_array<_Tp>(__alloc);
}
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
}
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
}
template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
}
// unbounded array variants
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
}
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
}
template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
_ForOverwriteAllocator __alloc(__a);
return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
}
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
}
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
}
template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
}
@@ -980,12 +986,14 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, const sh
}
template <class _Tp, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool
+operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
return !(__y < __x);
}
template <class _Tp, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool
+operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
return !(__x < __y);
}
@@ -1075,7 +1083,8 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __
}
template <class _Tp, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
+static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
@@ -1083,13 +1092,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_pt
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
#endif
template <class _Tp, class _Up>
-inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] inline
+ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
typedef typename shared_ptr<_Tp>::element_type _ET;
_ET* __p = dynamic_cast<_ET*>(__r.get());
return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
@@ -1099,14 +1109,14 @@ inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_p
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get());
return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>();
}
#endif
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
typedef typename shared_ptr<_Tp>::element_type _RTp;
return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
}
@@ -1115,13 +1125,13 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>&
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
#endif
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
@@ -1129,7 +1139,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<
// We don't backport because it is an evolutionary change.
#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Up>
-_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
#endif
@@ -1137,7 +1147,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&&
#if _LIBCPP_HAS_RTTI
template <class _Dp, class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
return __p.template __get_deleter<_Dp>();
}
@@ -1192,15 +1202,19 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
_LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }
- _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { return __cntrl_ == nullptr || __cntrl_->use_count() == 0; }
- _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
+ return __cntrl_ ? __cntrl_->use_count() : 0;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT {
+ return __cntrl_ == nullptr || __cntrl_->use_count() == 0;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
return __cntrl_ < __r.__cntrl_;
}
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
return __cntrl_ < __r.__cntrl_;
}
@@ -1384,13 +1398,15 @@ class enable_shared_from_this {
_LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {}
public:
- _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
- _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { return shared_ptr<const _Tp>(__weak_this_); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const {
+ return shared_ptr<const _Tp>(__weak_this_);
+ }
#if _LIBCPP_STD_VER >= 17
- _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
- _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
#endif // _LIBCPP_STD_VER >= 17
template <class _Up>
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 3cf4b97a7f49c..a822c761be203 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -258,14 +258,17 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
return *this;
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator*() const
_NOEXCEPT_(_NOEXCEPT_(*std::declval<pointer>())) {
return *__ptr_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __deleter_; }
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_; }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT {
+ return __deleter_;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type&
+ get_deleter() const _NOEXCEPT {
return __deleter_;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT {
@@ -672,8 +675,8 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
#endif
template <class _T1, class _D1>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
-operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
return !__x;
}
@@ -748,12 +751,13 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
#if _LIBCPP_STD_VER >= 14
template <class _Tp, class... _Args, enable_if_t<!is_array<_Tp>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(_Args&&... __args) {
return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));
}
template <class _Tp, enable_if_t<__is_unbounded_array_v<_Tp>, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique(size_t __n) {
typedef __remove_extent_t<_Tp> _Up;
return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);
}
@@ -766,12 +770,13 @@ void make_unique(_Args&&...) = delete;
#if _LIBCPP_STD_VER >= 20
template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite() {
return unique_ptr<_Tp>(new _Tp);
}
template <class _Tp, enable_if_t<is_unbounded_array_v<_Tp>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp> make_unique_for_overwrite(size_t __n) {
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr<_Tp>
+make_unique_for_overwrite(size_t __n) {
return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);
}
diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
index 57eb4f7cc0bf8..46c3263c79d9f 100644
--- a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
@@ -6,19 +6,147 @@
//
//===----------------------------------------------------------------------===//
-// REQUIRES: std-at-least-c++23
-
// <memory>
// Check that functions are marked [[nodiscard]]
#include <memory>
+#include <utility>
#include "test_macros.h"
void test() {
+ { // [unique.ptr]
+ std::unique_ptr<int> uPtr;
+
+ *uPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ uPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ uPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ const std::unique_ptr<int> cuPtr;
+ cuPtr.get_deleter(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 14
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique<int>(94);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique<int[]>(82);
+#endif
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique_for_overwrite<int>();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_unique_for_overwrite<int[]>(5);
+#endif
+ }
+ { // [util.sharedptr]
+ std::shared_ptr<int[]> sPtr;
+
+ sPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ *sPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.owner_before(std::shared_ptr<int>());
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.owner_before(std::weak_ptr<int>());
+#if TEST_STD_VER >= 17
+ sPtr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int>(std::allocator<int>(), 5);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int>();
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared_for_overwrite<int>(std::allocator<int>());
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared_for_overwrite<int>();
+
+ // Bounded array variants
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[5]>(std::allocator<int>());
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[5]>(std::allocator<int>(), 5);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared_for_overwrite<int[5]>(std::allocator<int>());
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[5]>();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[5]>(94);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared_for_overwrite<int[5]>();
+
+ // Unbounded array variants
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[]>(std::allocator<int>(), 5);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared<int[]>(std::allocator<int>(), 5, 94);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::allocate_shared_for_overwrite<int[]>(std::allocator<int>(), 5);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[]>(5);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared<int[]>(5, 82);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_shared_for_overwrite<int[]>(5);
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::static_pointer_cast<int[]>(sPtr);
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::static_pointer_cast<int[]>(std::move(sPtr));
+#endif
+ class Empty {};
+ std::shared_ptr<Empty> dsPtr;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::dynamic_pointer_cast<Empty>(dsPtr);
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::dynamic_pointer_cast<Empty>(std::move(dsPtr));
+#endif
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::const_pointer_cast<int[]>(sPtr);
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::const_pointer_cast<int[]>(std::move(sPtr));
+#endif
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::reinterpret_pointer_cast<int[]>(sPtr);
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::reinterpret_pointer_cast<int[]>(std::move(sPtr));
+#endif
+#if !defined(TEST_HAS_NO_RTTI)
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::get_deleter<int[]>(sPtr);
+#endif
+ }
+ { // [util.smartptr.weak]
+ std::weak_ptr<int> wPtr;
+
+ wPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.expired(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.lock(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.owner_before(std::weak_ptr<int>());
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ wPtr.owner_before(std::shared_ptr<int>());
+ }
+ { // [util.smartptr.enab]
+ class EnableShared : public std::enable_shared_from_this<EnableShared> {};
+ EnableShared es;
+ const EnableShared ces;
+
+ es.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ces.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 17
+ es.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ces.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+ }
#if TEST_STD_VER >= 23
- {
+ { // [smartptr.adapt]
std::unique_ptr<int> uPtr;
// [inout.ptr]
std::inout_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
>From ff03257f60b92710e60bb31fe4a7660a920ff987 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 18 Nov 2025 19:41:26 +0200
Subject: [PATCH 2/5] Addressed review comments
---
libcxx/include/__memory/shared_ptr.h | 10 +++---
libcxx/include/__memory/unique_ptr.h | 3 +-
.../utilities/smartptr/nodiscard.verify.cpp | 35 +++++++++----------
3 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index a470c673425fa..6eddc4daa4184 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -584,7 +584,9 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
}
#if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
- _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; }
+ [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT {
+ return use_count() == 1;
+ }
#endif
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; }
@@ -986,14 +988,12 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, const sh
}
template <class _Tp, class _Up>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool
-operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
return !(__y < __x);
}
template <class _Tp, class _Up>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI bool
-operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
return !(__x < __y);
}
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index a822c761be203..b5e2d79a3d1d8 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -675,8 +675,7 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
#endif
template <class _T1, class _D1>
-inline _LIBCPP_HIDE_FROM_ABI
-_LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
return !__x;
}
diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
index 46c3263c79d9f..641ffcb01528a 100644
--- a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
@@ -6,6 +6,10 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE
+
// <memory>
// Check that functions are marked [[nodiscard]]
@@ -44,19 +48,22 @@ void test() {
sPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
*sPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER <= 20
+ sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.owner_before(std::shared_ptr<int>());
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.owner_before(std::weak_ptr<int>());
-#if TEST_STD_VER >= 17
+# if TEST_STD_VER >= 17
sPtr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-#endif
+# endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::allocate_shared<int>(std::allocator<int>(), 5);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::make_shared<int>();
-#if TEST_STD_VER >= 20
+# if TEST_STD_VER >= 20
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::allocate_shared_for_overwrite<int>(std::allocator<int>());
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -89,38 +96,30 @@ void test() {
std::make_shared<int[]>(5, 82);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::make_shared_for_overwrite<int[]>(5);
-#endif
+# endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::static_pointer_cast<int[]>(sPtr);
-#if TEST_STD_VER >= 20
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::static_pointer_cast<int[]>(std::move(sPtr));
-#endif
class Empty {};
std::shared_ptr<Empty> dsPtr;
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::dynamic_pointer_cast<Empty>(dsPtr);
-#if TEST_STD_VER >= 20
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::dynamic_pointer_cast<Empty>(std::move(dsPtr));
-#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::const_pointer_cast<int[]>(sPtr);
-#if TEST_STD_VER >= 20
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::const_pointer_cast<int[]>(std::move(sPtr));
-#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::reinterpret_pointer_cast<int[]>(sPtr);
-#if TEST_STD_VER >= 20
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::reinterpret_pointer_cast<int[]>(std::move(sPtr));
-#endif
-#if !defined(TEST_HAS_NO_RTTI)
+# if !defined(TEST_HAS_NO_RTTI)
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::get_deleter<int[]>(sPtr);
-#endif
+# endif
}
{ // [util.smartptr.weak]
std::weak_ptr<int> wPtr;
@@ -140,12 +139,12 @@ void test() {
es.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
ces.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-#if TEST_STD_VER >= 17
+# if TEST_STD_VER >= 17
es.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
ces.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-#endif
+# endif
}
-#if TEST_STD_VER >= 23
+# if TEST_STD_VER >= 23
{ // [smartptr.adapt]
std::unique_ptr<int> uPtr;
// [inout.ptr]
@@ -153,5 +152,5 @@ void test() {
// [out.ptr]
std::out_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
-#endif
+# endif
}
>From 1fc645d0b154394d6519981739ce9da8280d3283 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 18 Nov 2025 19:50:39 +0200
Subject: [PATCH 3/5] Address comment
---
libcxx/include/__memory/unique_ptr.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index b5e2d79a3d1d8..b5f469365daed 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -675,7 +675,8 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
#endif
template <class _T1, class _D1>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
+operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT {
return !__x;
}
>From 94a8b14ae6da2de963e66d16a78d9522f2b5d19f Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 18 Nov 2025 19:53:48 +0200
Subject: [PATCH 4/5] Formatting
---
.../utilities/smartptr/nodiscard.verify.cpp | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
index 641ffcb01528a..7859b92e577c5 100644
--- a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
@@ -49,21 +49,21 @@ void test() {
*sPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#if TEST_STD_VER <= 20
- sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.owner_before(std::shared_ptr<int>());
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.owner_before(std::weak_ptr<int>());
-# if TEST_STD_VER >= 17
+#if TEST_STD_VER >= 17
sPtr[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-# endif
+#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::allocate_shared<int>(std::allocator<int>(), 5);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::make_shared<int>();
-# if TEST_STD_VER >= 20
+#if TEST_STD_VER >= 20
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::allocate_shared_for_overwrite<int>(std::allocator<int>());
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -96,7 +96,7 @@ void test() {
std::make_shared<int[]>(5, 82);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::make_shared_for_overwrite<int[]>(5);
-# endif
+#endif
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::static_pointer_cast<int[]>(sPtr);
@@ -116,10 +116,10 @@ void test() {
std::reinterpret_pointer_cast<int[]>(sPtr);
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::reinterpret_pointer_cast<int[]>(std::move(sPtr));
-# if !defined(TEST_HAS_NO_RTTI)
+#if !defined(TEST_HAS_NO_RTTI)
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::get_deleter<int[]>(sPtr);
-# endif
+#endif
}
{ // [util.smartptr.weak]
std::weak_ptr<int> wPtr;
@@ -139,12 +139,12 @@ void test() {
es.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
ces.shared_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-# if TEST_STD_VER >= 17
+#if TEST_STD_VER >= 17
es.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
ces.weak_from_this(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-# endif
+#endif
}
-# if TEST_STD_VER >= 23
+#if TEST_STD_VER >= 23
{ // [smartptr.adapt]
std::unique_ptr<int> uPtr;
// [inout.ptr]
@@ -152,5 +152,5 @@ void test() {
// [out.ptr]
std::out_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
-# endif
+#endif
}
>From 7b15b466cfe35a00291a81e0d7cf869f9e174f97 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 18 Nov 2025 20:08:29 +0200
Subject: [PATCH 5/5] Cleanup
---
libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
index 7859b92e577c5..e48b017f5a34d 100644
--- a/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
@@ -48,9 +48,7 @@ void test() {
sPtr.get(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
*sPtr; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.use_count(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-#if TEST_STD_VER <= 20
- sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-#endif
+ sPtr.unique(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
sPtr.owner_before(std::shared_ptr<int>());
// expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
More information about the libcxx-commits
mailing list