[committed] libstdc++: Add [[nodiscard]] to std::span members

Message ID 20231111004440.77760-1-jwakely@redhat.com
State Accepted
Headers
Series [committed] libstdc++: Add [[nodiscard]] to std::span members |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Jonathan Wakely Nov. 11, 2023, 12:44 a.m. UTC
  Tested x86_64-linux. Pushed to trunk.

-- >8 --

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.
---
 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 +-
 .../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 +++++++++++++++++++
 .../span/subspan_2_assert_neg.cc              |  2 +-
 .../span/subspan_3_assert_neg.cc              |  2 +-
 .../span/subspan_4_assert_neg.cc              |  2 +-
 .../span/subspan_5_assert_neg.cc              |  2 +-
 .../span/subspan_6_assert_neg.cc              |  2 +-
 .../23_containers/span/subspan_assert_neg.cc  |  2 +-
 .../23_containers/span/subspan_neg.cc         |  6 +-
 21 files changed, 103 insertions(+), 23 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/23_containers/span/nodiscard.cc
  

Patch

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<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 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<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 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<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 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<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 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<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 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<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 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<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 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<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 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<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 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<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 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<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 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<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 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<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 00000000000..3bccd1545c3
--- /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 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<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 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<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 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<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 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<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 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<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 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<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 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<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 }