[libcxx-commits] [libcxx] [libc++][ranges] Applied `[[nodiscard]]` to `all`, `owning_view`, `ref_view` (PR #173708)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Dec 26 22:02:43 PST 2025
https://github.com/H-G-Hristov created https://github.com/llvm/llvm-project/pull/173708
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html
- https://wg21.link/range.all
Towards #172124
>From 32fdde61d67889c803c45ef1e3aaf82519ecf38b Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 27 Dec 2025 08:02:16 +0200
Subject: [PATCH] [libc++][ranges] Applied `[[nodiscard]]` to `all`,
`owning_view`, `ref_view`
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html
- https://wg21.link/range.all
Towards #172124
---
libcxx/include/__ranges/owning_view.h | 30 +++----
libcxx/include/__ranges/ref_view.h | 12 +--
.../range.all/all.nodiscard.verify.cpp | 21 -----
.../range.all/nodiscard.verify.cpp | 83 +++++++++++++++++++
4 files changed, 104 insertions(+), 42 deletions(-)
delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp
diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h
index 254bdb4329119..1ab81afee774a 100644
--- a/libcxx/include/__ranges/owning_view.h
+++ b/libcxx/include/__ranges/owning_view.h
@@ -49,52 +49,52 @@ class owning_view : public view_interface<owning_view<_Rp>> {
_LIBCPP_HIDE_FROM_ABI owning_view(owning_view&&) = default;
_LIBCPP_HIDE_FROM_ABI owning_view& operator=(owning_view&&) = default;
- _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
- _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
- _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); }
- _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); }
-
- _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); }
- _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); }
- _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
requires range<const _Rp>
{
return ranges::begin(__r_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
requires range<const _Rp>
{
return ranges::end(__r_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
requires requires { ranges::empty(__r_); }
{
return ranges::empty(__r_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
requires requires { ranges::empty(__r_); }
{
return ranges::empty(__r_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size()
requires sized_range<_Rp>
{
return ranges::size(__r_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
requires sized_range<const _Rp>
{
return ranges::size(__r_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto data()
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data()
requires contiguous_range<_Rp>
{
return ranges::data(__r_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
requires contiguous_range<const _Rp>
{
return ranges::data(__r_);
diff --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h
index 5329d778dd30d..109a10cec299e 100644
--- a/libcxx/include/__ranges/ref_view.h
+++ b/libcxx/include/__ranges/ref_view.h
@@ -51,24 +51,24 @@ class ref_view : public view_interface<ref_view<_Range>> {
_LIBCPP_HIDE_FROM_ABI constexpr ref_view(_Tp&& __t)
: __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t)))) {}
- _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
- _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
- _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); }
- _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
requires requires { ranges::empty(*__range_); }
{
return ranges::empty(*__range_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
requires sized_range<_Range>
{
return ranges::size(*__range_);
}
- _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
requires contiguous_range<_Range>
{
return ranges::data(*__range_);
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp
deleted file mode 100644
index 43b9ebf60f2a0..0000000000000
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp
+++ /dev/null
@@ -1,21 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// Test the libc++ extension that std::views::all is marked as [[nodiscard]].
-
-#include <ranges>
-
-void test() {
- int range[] = {1, 2, 3};
-
- std::views::all(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- range | std::views::all; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
- std::views::all | std::views::all; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..eaa739ca87c13
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.all/nodiscard.verify.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++20
+
+// Test that functions are marked as [[nodiscard]].
+
+#include <ranges>
+#include <vector>
+#include <utility>
+
+void test() {
+ std::vector<int> range;
+
+ { // [range.all.general]
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all(range);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::views::all;
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all | std::views::all;
+ }
+
+ { // [range.owning.view]
+ std::ranges::owning_view v{std::ranges::subrange(range)};
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.base();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).base();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(v).base();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(std::as_const(v)).base();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.end();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).end();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.empty();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).empty();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.size();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).size();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.data();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::as_const(v).data();
+ }
+
+ { // [range.ref.view]
+ std::ranges::ref_view v{range};
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.base();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.begin();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.end();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.size();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ v.data();
+ }
+}
More information about the libcxx-commits
mailing list