[libcxx-commits] [libcxx] [libc++][forward_list] Applied `[[nodiscard]]` (PR #169019)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Nov 24 02:22:57 PST 2025
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/169019
>From 9e4e5b39cc581a2dfec777f2e383aa3b6761bf6b Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 21 Nov 2025 10:45:16 +0200
Subject: [PATCH 1/2] [libc++][forward_list] Applied `[[nodiscard]]`
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html#apply-nodiscard-where-relevant
---
libcxx/include/forward_list | 49 ++++++++++---------
.../forward_list.nodiscard.verify.cpp | 25 +++++++++-
2 files changed, 49 insertions(+), 25 deletions(-)
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 272e52d68f46a..550bacb4ee8d6 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -732,50 +732,52 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
return allocator_type(this->__alloc_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {
return iterator(__base::__before_begin()->__next_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
return const_iterator(__base::__before_begin()->__next_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(nullptr); }
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {
+ return iterator(nullptr);
+ }
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {
return const_iterator(nullptr);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
return const_iterator(__base::__before_begin()->__next_);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
return const_iterator(nullptr);
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT {
return iterator(__base::__before_begin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
return const_iterator(__base::__before_begin());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
return const_iterator(__base::__before_begin());
}
[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
return __base::__before_begin()->__next_ == nullptr;
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
return std::min<size_type>(__node_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() {
_LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
return __base::__before_begin()->__next_->__get_value();
}
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
+ [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const {
_LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
return __base::__before_begin()->__next_->__get_value();
}
@@ -822,15 +824,15 @@ public:
# if _LIBCPP_STD_VER >= 23
template <_ContainerCompatibleRange<_Tp> _Range>
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator
- insert_range_after(const_iterator __position, _Range&& __range) {
+ _LIBCPP_CONSTEXPR_SINCE_CXX26
+ _LIBCPP_HIDE_FROM_ABI iterator insert_range_after(const_iterator __position, _Range&& __range) {
return __insert_after_with_sentinel(__position, ranges::begin(__range), ranges::end(__range));
}
# endif
template <class _InputIterator, class _Sentinel>
- _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator
- __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l);
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI
+ iterator __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l);
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p);
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l);
@@ -1516,8 +1518,8 @@ operator==(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>
# if _LIBCPP_STD_VER <= 17
template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI bool
-operator!=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline
+ _LIBCPP_HIDE_FROM_ABI bool operator!=(const forward_list<_Tp, _Alloc>& __x, const forward_list<_Tp, _Alloc>& __y) {
return !(__x == __y);
}
@@ -1556,15 +1558,16 @@ operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _A
# endif // #if _LIBCPP_STD_VER <= 17
template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI void
-swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline
+ _LIBCPP_HIDE_FROM_ABI void swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
+ _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
__x.swap(__y);
}
# if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Allocator, class _Predicate>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Allocator>::size_type
-erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI
+typename forward_list<_Tp, _Allocator>::size_type erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
return __c.remove_if(__pred);
}
diff --git a/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp
index 7594a1d299a50..671c7f71ab2a2 100644
--- a/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp
@@ -13,6 +13,27 @@
#include <forward_list>
void test() {
- std::forward_list<int> forward_list;
- forward_list.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::forward_list<int> fl;
+ const std::forward_list<int> cfl;
+
+ fl.get_allocator(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.before_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.before_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.cbefore_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.cbefore_begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fl.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fl.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ fl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ cfl.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
>From d93f85dcd33c736053937e1d909a4ac809b2947f Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 24 Nov 2025 12:22:39 +0200
Subject: [PATCH 2/2] Addressed comments
---
libcxx/include/forward_list | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 550bacb4ee8d6..8419ea4c0474a 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -1558,16 +1558,15 @@ operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _A
# endif // #if _LIBCPP_STD_VER <= 17
template <class _Tp, class _Alloc>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline
- _LIBCPP_HIDE_FROM_ABI void swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
- _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI void
+swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
__x.swap(__y);
}
# if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Allocator, class _Predicate>
-_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI
-typename forward_list<_Tp, _Allocator>::size_type erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI typename forward_list<_Tp, _Allocator>::size_type
+erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
return __c.remove_if(__pred);
}
More information about the libcxx-commits
mailing list