diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2023-11-04 08:30:54 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2023-11-11 00:41:08 +0000 |
commit | a92a434024c59f57dc24328d946f97a5e71cee94 (patch) | |
tree | f624f9ed450fcfec8ada600793b34d0044b00d2c | |
parent | 898fd81b831c106859bc99e65c7c1cbb642320c8 (diff) | |
download | gcc-a92a434024c59f57dc24328d946f97a5e71cee94.zip gcc-a92a434024c59f57dc24328d946f97a5e71cee94.tar.gz gcc-a92a434024c59f57dc24328d946f97a5e71cee94.tar.bz2 |
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.
21 files changed, 103 insertions, 23 deletions
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span index d5644a19..90d08f1 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<size_t _Count> + [[nodiscard]] constexpr span<element_type, _Count> first() const noexcept { @@ -335,6 +351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Sp{ this->data(), _Count }; } + [[nodiscard]] constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { @@ -343,6 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<size_t _Count> + [[nodiscard]] constexpr span<element_type, _Count> last() const noexcept { @@ -354,6 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Sp{ this->data() + (this->size() - _Count), _Count }; } + [[nodiscard]] constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { @@ -362,6 +381,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<size_t _Offset, size_t _Count = dynamic_extent> + [[nodiscard]] constexpr auto subspan() const noexcept -> span<element_type, _S_subspan_extent<_Offset, _Count>()> @@ -393,6 +413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + [[nodiscard]] constexpr span<element_type, dynamic_extent> subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept @@ -434,6 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION -> span<remove_reference_t<ranges::range_reference_t<_Range&>>>; template<typename _Type, size_t _Extent> + [[nodiscard]] inline span<const byte, _Extent == dynamic_extent ? dynamic_extent : _Extent * sizeof(_Type)> @@ -451,7 +473,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline span<byte, _Extent == dynamic_extent ? dynamic_extent : _Extent * sizeof(_Type)> - as_writable_bytes(span<_Type, _Extent> __sp) noexcept + as_writable_bytes [[nodiscard]] (span<_Type, _Extent> __sp) noexcept { auto data = reinterpret_cast<byte*>(__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 b42aea3..7148024 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<int, std::dynamic_extent> 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 d3ea4f4..dce512a 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<int, 0> 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 876a6b7..d885268 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<int, std::dynamic_extent> 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 f1d8cdc..829818c 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<int, std::dynamic_extent> 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 4a8cd18..c47b8db 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<int, 4> 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 12cbd4a..5dd9c96 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<int, std::dynamic_extent> 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 b5525db..b2c5e9c 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<int, 0> 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 c75924e..9a62bdd 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<int, std::dynamic_extent> 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 6e8cd49..a2cdb8a4 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<int, 0> 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 a464fa5..8643939 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<int, std::dynamic_extent> 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 f36db45..a32246a 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<int, std::dynamic_extent> 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 2e86233..c85668a 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<int, 2> 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 0000000..3bccd15 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/span/nodiscard.cc @@ -0,0 +1,58 @@ +// { dg-do compile { target c++20 } } + +#include <span> + +void +test_observers(std::span<int> 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<float> 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) +{ + 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<long, 20> 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, 20> 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 12b79ff..3151f54 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<int, std::dynamic_extent> 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 3130a50..4bb29fe 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<int, std::dynamic_extent> 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 2a57ddf..eee4d55 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<int, std::dynamic_extent> 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 48aaeaf..705359d 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<int, std::dynamic_extent> 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 2c90c5e..21715a1 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<int, std::dynamic_extent> 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 4873c75..ee35e87 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<int, std::dynamic_extent> 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 3c69f23..8c1d2bb 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<int, 4> 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<int, 4> 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<int, 4> s(a); - s.subspan<3, 2>(); // { dg-error "here" } + (void) s.subspan<3, 2>(); // { dg-error "here" } } // { dg-error "static assertion failed" "" { target *-*-* } 0 } |