From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 946163885535; Sat, 11 Nov 2023 00:43:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 946163885535 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1699663433; bh=7wvZ2qjbJe3Tr6RafaIgTL9qv3TAokESjNd/+tiUUgE=; h=From:To:Subject:Date:From; b=c4ATvkYgnFX7oLRqZ4cT8zr4c4qYADfIxb2A+Hh3xkCdG7Y9HDnXy4+D/yfW3wX2Y vxnl9583xKAyPqmSXi2kFHodqFK49qjBtUZDUt+dAu36+BCgHWi1qUrrii0Y8w8tTD fFId8FeTSsNwvQ2bwdiNz3CtqPXQxQuUNUlLCYOc= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r14-5343] libstdc++: Add [[nodiscard]] to std::span members X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/master X-Git-Oldrev: 898fd81b831c106859bc99e65c7c1cbb642320c8 X-Git-Newrev: a92a434024c59f57dc24328d946f97a5e71cee94 Message-Id: <20231111004353.946163885535@sourceware.org> Date: Sat, 11 Nov 2023 00:43:53 +0000 (GMT) List-Id: https://gcc.gnu.org/g:a92a434024c59f57dc24328d946f97a5e71cee94 commit r14-5343-ga92a434024c59f57dc24328d946f97a5e71cee94 Author: Jonathan Wakely Date: Sat Nov 4 08:30:54 2023 +0000 libstdc++: Add [[nodiscard]] to std::span members All std::span member functions are pure functions that have no side effects. They are only useful for their return value, so they should all warn if that value is not used. libstdc++-v3/ChangeLog: * include/std/span (span, as_bytes, as_writable_bytes): Add [[nodiscard]] attribute on all non-void functions. * testsuite/23_containers/span/back_assert_neg.cc: Suppress nodiscard warning. * testsuite/23_containers/span/back_neg.cc: Likewise. * testsuite/23_containers/span/first_2_assert_neg.cc: Likewise. * testsuite/23_containers/span/first_assert_neg.cc: Likewise. * testsuite/23_containers/span/first_neg.cc: Likewise. * testsuite/23_containers/span/front_assert_neg.cc: Likewise. * testsuite/23_containers/span/front_neg.cc: Likewise. * testsuite/23_containers/span/index_op_assert_neg.cc: Likewise. * testsuite/23_containers/span/index_op_neg.cc: Likewise. * testsuite/23_containers/span/last_2_assert_neg.cc: Likewise. * testsuite/23_containers/span/last_assert_neg.cc: Likewise. * testsuite/23_containers/span/last_neg.cc: Likewise. * testsuite/23_containers/span/subspan_2_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_3_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_4_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_5_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_6_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_assert_neg.cc: Likewise. * testsuite/23_containers/span/subspan_neg.cc: Likewise. * testsuite/23_containers/span/nodiscard.cc: New test. Diff: --- libstdc++-v3/include/std/span | 26 +++++++++- .../23_containers/span/back_assert_neg.cc | 2 +- .../testsuite/23_containers/span/back_neg.cc | 2 +- .../23_containers/span/first_2_assert_neg.cc | 2 +- .../23_containers/span/first_assert_neg.cc | 2 +- .../testsuite/23_containers/span/first_neg.cc | 2 +- .../23_containers/span/front_assert_neg.cc | 2 +- .../testsuite/23_containers/span/front_neg.cc | 2 +- .../23_containers/span/index_op_assert_neg.cc | 2 +- .../testsuite/23_containers/span/index_op_neg.cc | 2 +- .../23_containers/span/last_2_assert_neg.cc | 2 +- .../23_containers/span/last_assert_neg.cc | 2 +- .../testsuite/23_containers/span/last_neg.cc | 2 +- .../testsuite/23_containers/span/nodiscard.cc | 58 ++++++++++++++++++++++ .../23_containers/span/subspan_2_assert_neg.cc | 2 +- .../23_containers/span/subspan_3_assert_neg.cc | 2 +- .../23_containers/span/subspan_4_assert_neg.cc | 2 +- .../23_containers/span/subspan_5_assert_neg.cc | 2 +- .../23_containers/span/subspan_6_assert_neg.cc | 2 +- .../23_containers/span/subspan_assert_neg.cc | 2 +- .../testsuite/23_containers/span/subspan_neg.cc | 6 +-- 21 files changed, 103 insertions(+), 23 deletions(-) diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index d5644a196a2..90d08f18d2c 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -246,20 +246,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // observers + [[nodiscard]] constexpr size_type size() const noexcept { return this->_M_extent._M_extent(); } + [[nodiscard]] constexpr size_type size_bytes() const noexcept { return this->_M_extent._M_extent() * sizeof(element_type); } - [[nodiscard]] constexpr bool + [[nodiscard]] + constexpr bool empty() const noexcept { return size() == 0; } // element access + [[nodiscard]] constexpr reference front() const noexcept { @@ -267,6 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this->_M_ptr; } + [[nodiscard]] constexpr reference back() const noexcept { @@ -274,6 +279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *(this->_M_ptr + (size() - 1)); } + [[nodiscard]] constexpr reference operator[](size_type __idx) const noexcept { @@ -281,41 +287,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *(this->_M_ptr + __idx); } + [[nodiscard]] constexpr pointer data() const noexcept { return this->_M_ptr; } // iterator support + [[nodiscard]] constexpr iterator begin() const noexcept { return iterator(this->_M_ptr); } + [[nodiscard]] constexpr iterator end() const noexcept { return iterator(this->_M_ptr + this->size()); } + [[nodiscard]] constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(this->end()); } + [[nodiscard]] constexpr reverse_iterator rend() const noexcept { return reverse_iterator(this->begin()); } #if __cplusplus > 202002L + [[nodiscard]] constexpr const_iterator cbegin() const noexcept { return begin(); } + [[nodiscard]] constexpr const_iterator cend() const noexcept { return end(); } + [[nodiscard]] constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); } + [[nodiscard]] constexpr const_reverse_iterator crend() const noexcept { return rend(); } @@ -324,6 +339,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // subviews template + [[nodiscard]] constexpr span first() const noexcept { @@ -335,6 +351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Sp{ this->data(), _Count }; } + [[nodiscard]] constexpr span first(size_type __count) const noexcept { @@ -343,6 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[nodiscard]] constexpr span last() const noexcept { @@ -354,6 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Sp{ this->data() + (this->size() - _Count), _Count }; } + [[nodiscard]] constexpr span last(size_type __count) const noexcept { @@ -362,6 +381,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[nodiscard]] constexpr auto subspan() const noexcept -> span()> @@ -393,6 +413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + [[nodiscard]] constexpr span subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept @@ -434,6 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION -> span>>; template + [[nodiscard]] inline span @@ -451,7 +473,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline span - as_writable_bytes(span<_Type, _Extent> __sp) noexcept + as_writable_bytes [[nodiscard]] (span<_Type, _Extent> __sp) noexcept { auto data = reinterpret_cast(__sp.data()); auto size = __sp.size_bytes(); diff --git a/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc index b42aea3b4b4..71480246fed 100644 --- a/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc @@ -25,5 +25,5 @@ int main() { std::span s; - s.back(); + (void) s.back(); } diff --git a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc index d3ea4f405f4..dce512aa1c8 100644 --- a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc @@ -24,7 +24,7 @@ test01(bool b) { std::span s; if (b || !s.empty()) - s.back(); + (void) s.back(); return true; } diff --git a/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc index 876a6b773d6..d885268c96c 100644 --- a/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.first(5); + (void) s.first(5); } diff --git a/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc index f1d8cdccb9b..829818c65c2 100644 --- a/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.first<5>(); + (void) s.first<5>(); } diff --git a/libstdc++-v3/testsuite/23_containers/span/first_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_neg.cc index 4a8cd184172..c47b8db7281 100644 --- a/libstdc++-v3/testsuite/23_containers/span/first_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/first_neg.cc @@ -24,6 +24,6 @@ test01() { int a[4]; std::span s(a); - s.first<5>(); // { dg-error "here" } + (void) s.first<5>(); // { dg-error "here" } } // { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc index 12cbd4a80ae..5dd9c963677 100644 --- a/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc @@ -25,5 +25,5 @@ int main() { std::span s; - s.front(); + (void) s.front(); } diff --git a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc index b5525db8f1d..b2c5e9cae32 100644 --- a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc @@ -24,7 +24,7 @@ test01(bool b) { std::span s; if (b || !s.empty()) - s.front(); + (void) s.front(); return true; } diff --git a/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc index c75924e5f38..9a62bdd3233 100644 --- a/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc @@ -25,5 +25,5 @@ int main() { std::span s; - s[99]; + (void) s[99]; } diff --git a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc index 6e8cd4903b3..a2cdb8a44c7 100644 --- a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc @@ -24,7 +24,7 @@ test01(bool b) { std::span s; if (b || !s.empty()) - s[99]; + (void) s[99]; return true; } diff --git a/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc index a464fa516b0..86439392e2c 100644 --- a/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.last(5); + (void) s.last(5); } diff --git a/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc index f36db455519..a32246ada47 100644 --- a/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.last<5>(); + (void) s.last<5>(); } diff --git a/libstdc++-v3/testsuite/23_containers/span/last_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_neg.cc index 2e86233f19a..c85668ab128 100644 --- a/libstdc++-v3/testsuite/23_containers/span/last_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/last_neg.cc @@ -24,6 +24,6 @@ test01() { int a[2]; std::span s(a); - s.last<3>(); // { dg-error "here" } + (void) s.last<3>(); // { dg-error "here" } } // { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/span/nodiscard.cc b/libstdc++-v3/testsuite/23_containers/span/nodiscard.cc new file mode 100644 index 00000000000..3bccd1545c3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/span/nodiscard.cc @@ -0,0 +1,58 @@ +// { dg-do compile { target c++20 } } + +#include + +void +test_observers(std::span s) +{ + s.size(); // { dg-warning "ignoring return value" } + s.size_bytes(); // { dg-warning "ignoring return value" } + s.empty(); // { dg-warning "ignoring return value" } +} + +void +test_element_access(std::span s) +{ + s.front(); // { dg-warning "ignoring return value" } + s.back(); // { dg-warning "ignoring return value" } + s[1]; // { dg-warning "ignoring return value" } + s.data(); // { dg-warning "ignoring return value" } +} + +struct S { }; + +void +test_iterators(std::span s) +{ + s.begin(); // { dg-warning "ignoring return value" } + s.end(); // { dg-warning "ignoring return value" } + s.rbegin(); // { dg-warning "ignoring return value" } + s.rend(); // { dg-warning "ignoring return value" } + +#if __cplusplus > 202002L + s.cbegin(); // { dg-warning "ignoring return value" "" { target c++23 } } + s.cend(); // { dg-warning "ignoring return value" "" { target c++23 } } + s.crbegin(); // { dg-warning "ignoring return value" "" { target c++23 } } + s.crend(); // { dg-warning "ignoring return value" "" { target c++23 } } +#endif +} + +void +test_subviews(std::span s) +{ + s.first<5>(); // { dg-warning "ignoring return value" } + s.first(6); // { dg-warning "ignoring return value" } + s.last<7>(); // { dg-warning "ignoring return value" } + s.last(8); // { dg-warning "ignoring return value" } + s.subspan<1>(); // { dg-warning "ignoring return value" } + s.subspan<2, 3>(); // { dg-warning "ignoring return value" } + s.subspan(4); // { dg-warning "ignoring return value" } + s.subspan(5, 6); // { dg-warning "ignoring return value" } +} + +void +test_non_members(std::span s) +{ + std::as_bytes(s); // { dg-warning "ignoring return value" } + std::as_writable_bytes(s); // { dg-warning "ignoring return value" } +} diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc index 12b79fffc5d..3151f544a24 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.subspan<2, 5>(); + (void) s.subspan<2, 5>(); } diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc index 3130a503534..4bb29fe99d6 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.subspan<2, 3>(); + (void) s.subspan<2, 3>(); } diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc index 2a57ddf48b8..eee4d558feb 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.subspan(5, 0); + (void) s.subspan(5, 0); } diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc index 48aaeaffbbf..705359d504e 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.subspan(2, 5); + (void) s.subspan(2, 5); } diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc index 2c90c5e67f8..21715a1a343 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.subspan(2, 3); + (void) s.subspan(2, 3); } diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc index 4873c757996..ee35e874b6d 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc @@ -26,5 +26,5 @@ int main() { int a[4]; std::span s(a); - s.subspan<5, 0>(); + (void) s.subspan<5, 0>(); } diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc index 3c69f236755..8c1d2bbfeef 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc @@ -24,7 +24,7 @@ test01() { int a[4]; std::span s(a); - s.subspan<5, 0>(); // { dg-error "here" } + (void) s.subspan<5, 0>(); // { dg-error "here" } } void @@ -32,7 +32,7 @@ test02() { int a[4]; std::span s(a); - s.subspan<3, 5>(); // { dg-error "here" } + (void) s.subspan<3, 5>(); // { dg-error "here" } } void @@ -40,7 +40,7 @@ test03() { int a[4]; std::span s(a); - s.subspan<3, 2>(); // { dg-error "here" } + (void) s.subspan<3, 2>(); // { dg-error "here" } } // { dg-error "static assertion failed" "" { target *-*-* } 0 }