From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 0FA64385840C; Tue, 12 Mar 2024 14:17:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0FA64385840C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1710253046; bh=RGSzoLwJqpTrB8xGKmxbsaX+YT20wDiYVpu3IKODUI8=; h=From:To:Subject:Date:From; b=QOhuNsVNknCb8Us8ZeUTz6HnkHYYCFRNwaZE90+K6iqdQ5PTt4ilkDKKvJX7Rxyle eThL8g1dBxfPK1EqIHWLhfnpJ4g4YO8c24I+WHWw+3u2g1v/vh5igcY8nQ3iLKilx/ l8jHVn2wsGWb6JzeXCMvioJGzMT020Q14KQxyedY= 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 r13-8423] libstdc++: Add [[nodiscard]] to std::span members X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/releases/gcc-13 X-Git-Oldrev: 66c55e4f57135f2df09daeea94e0900862c54799 X-Git-Newrev: 779563cff2e18e7891abf57aeee90e8db5035eb5 Message-Id: <20240312141726.0FA64385840C@sourceware.org> Date: Tue, 12 Mar 2024 14:17:26 +0000 (GMT) List-Id: https://gcc.gnu.org/g:779563cff2e18e7891abf57aeee90e8db5035eb5 commit r13-8423-g779563cff2e18e7891abf57aeee90e8db5035eb5 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. (cherry picked from commit a92a434024c59f57dc24328d946f97a5e71cee94) 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 67633899665..b70893779d8 100644 --- a/libstdc++-v3/include/std/span +++ b/libstdc++-v3/include/std/span @@ -248,20 +248,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 { @@ -269,6 +273,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this->_M_ptr; } + [[nodiscard]] constexpr reference back() const noexcept { @@ -276,6 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *(this->_M_ptr + (size() - 1)); } + [[nodiscard]] constexpr reference operator[](size_type __idx) const noexcept { @@ -283,41 +289,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(); } @@ -326,6 +341,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // subviews template + [[nodiscard]] constexpr span first() const noexcept { @@ -337,6 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Sp{ this->data(), _Count }; } + [[nodiscard]] constexpr span first(size_type __count) const noexcept { @@ -345,6 +362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[nodiscard]] constexpr span last() const noexcept { @@ -356,6 +374,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Sp{ this->data() + (this->size() - _Count), _Count }; } + [[nodiscard]] constexpr span last(size_type __count) const noexcept { @@ -364,6 +383,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + [[nodiscard]] constexpr auto subspan() const noexcept -> span()> @@ -395,6 +415,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + [[nodiscard]] constexpr span subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept @@ -436,6 +457,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION -> span>>; template + [[nodiscard]] inline span @@ -453,7 +475,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 2b4dee6df9a..a7048977f47 100644 --- a/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc @@ -26,5 +26,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 01083e60168..8c252a7ea69 100644 --- a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc @@ -25,7 +25,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 93cd095495a..4220a6bca0e 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 @@ -27,5 +27,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 4ff56bf65cf..26c6483f1d7 100644 --- a/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc @@ -27,5 +27,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 8ed68296263..79010701727 100644 --- a/libstdc++-v3/testsuite/23_containers/span/first_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/first_neg.cc @@ -25,6 +25,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 2d4320d0fd9..e1b1ad3287e 100644 --- a/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc @@ -26,5 +26,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 f8e8100bd7c..8e688d30fd3 100644 --- a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc @@ -25,7 +25,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 b2633cbfaab..8a7ef3d1464 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 @@ -26,5 +26,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 8bbe8ea0737..810a7c2aa23 100644 --- a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc @@ -25,7 +25,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 906896911c0..6046264593b 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 @@ -27,5 +27,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 59cd44acc3c..a1a4def2b8b 100644 --- a/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc @@ -27,5 +27,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 9c360d2650e..dc2e99ad0fd 100644 --- a/libstdc++-v3/testsuite/23_containers/span/last_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/last_neg.cc @@ -25,6 +25,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 488b5606993..b047cbe57b4 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 @@ -27,5 +27,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 8324edfc49a..154e5874449 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 @@ -27,5 +27,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 b1dbfe6902e..1757c4efaed 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 @@ -27,5 +27,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 2102fd02cce..d327f557c22 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 @@ -27,5 +27,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 c003561032c..a4227948f55 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 @@ -27,5 +27,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 c46b78fe8bc..1b4b63a22af 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc @@ -27,5 +27,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 205bafd39dd..4ff764a3724 100644 --- a/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc @@ -25,7 +25,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 @@ -33,7 +33,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 @@ -41,7 +41,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 }