]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Add [[nodiscard]] to std::span members
authorJonathan Wakely <jwakely@redhat.com>
Sat, 4 Nov 2023 08:30:54 +0000 (08:30 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Sat, 11 Nov 2023 00:41:08 +0000 (00:41 +0000)
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:
libstdc++-v3/include/std/span
libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/back_neg.cc
libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/first_neg.cc
libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/front_neg.cc
libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc
libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/last_neg.cc
libstdc++-v3/testsuite/23_containers/span/nodiscard.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc
libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc

index d5644a196a2a8f50a888ca288fee5e3d87fc8a9c..90d08f18d2c043f17ce8b975ace3cced523ca822 100644 (file)
@@ -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();
index b42aea3b4b401a53ee32dc76b649c56c5f8e8c22..71480246feddbb037ab52c02d7a14e96b5f0baef 100644 (file)
@@ -25,5 +25,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s.back();
+  (void) s.back();
 }
index d3ea4f405f431c87427ff1f9d5ef760149bd8d27..dce512aa1c83503b982d018d48911f244f79fa39 100644 (file)
@@ -24,7 +24,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s.back();
+    (void) s.back();
   return true;
 }
 
index 876a6b773d63e05d21da5597d55f5db36fe29eef..d885268c96c32836491f7ebfedcb1f267dc05f3c 100644 (file)
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.first(5);
+  (void) s.first(5);
 }
index f1d8cdccb9bec200f0da1c2706d75e0295d3be8a..829818c65c24a7aa930c0b8a46bfb832f54606e7 100644 (file)
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.first<5>();
+  (void) s.first<5>();
 }
index 4a8cd18417218c23ad1d08fc05cc9f02de6be9ca..c47b8db72817017061d5bb955b7f0d4d5a364a68 100644 (file)
@@ -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 }
index 12cbd4a80aefd767d0c323d49ec893efcaac0173..5dd9c96367742e85b45b5990bc2fecc5aed9eed8 100644 (file)
@@ -25,5 +25,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s.front();
+  (void) s.front();
 }
index b5525db8f1d9a5a72d0217aa2b4d9ef8157c675b..b2c5e9cae320c8856c527497a2b05cddbc6e684f 100644 (file)
@@ -24,7 +24,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s.front();
+    (void) s.front();
   return true;
 }
 
index c75924e5f38b362bc5f72c456619319d1814dd5f..9a62bdd3233edd61ab8739a2279e2a1d97db0c56 100644 (file)
@@ -25,5 +25,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s[99];
+  (void) s[99];
 }
index 6e8cd4903b35e47c65e9130a07c15ad05e13b031..a2cdb8a44c7dabfe5d66d98b9946c4a42fc9e59d 100644 (file)
@@ -24,7 +24,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s[99];
+    (void) s[99];
   return true;
 }
 
index a464fa516b076159011a39a46b5c3d17193af3ef..86439392e2cfed3543a1d7b89317f588082a081f 100644 (file)
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.last(5);
+  (void) s.last(5);
 }
index f36db455519d4d13b8c0efba7d72d1d8c396df37..a32246ada4789a90825f9eb004dd62a8bc948d4b 100644 (file)
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.last<5>();
+  (void) s.last<5>();
 }
index 2e86233f19a4991246f941648b0faaa893f6a020..c85668ab12846c18ba2e013a337fead118c8c0fc 100644 (file)
@@ -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 (file)
index 0000000..3bccd15
--- /dev/null
@@ -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" }
+}
index 12b79fffc5d5e14500d74bfe5c617c7341c0b3d0..3151f544a2493a5e4d80aba0445b516da7ef0f43 100644 (file)
@@ -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>();
 }
index 3130a503534877903bfc98f63ff6e099335cbc95..4bb29fe99d67ec4c9c976ca2b18bbed0496386b8 100644 (file)
@@ -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>();
 }
index 2a57ddf48b8eae5bb825b2dac15b260a6090f109..eee4d558feb4ff0f9b1ac0733e821d02d68ed19e 100644 (file)
@@ -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);
 }
index 48aaeaffbbfcfe81b097491631d5c8ca69a7fd9d..705359d504eeb1686b97ce18043bc919d1429784 100644 (file)
@@ -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);
 }
index 2c90c5e67f8367f77938eb36c989c3661a628cfc..21715a1a343ed472d808b3bbcd96205c92cb4794 100644 (file)
@@ -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);
 }
index 4873c7579965d0734afc650aa9a4ed9fcf700c41..ee35e874b6d345fd7e1ea0e66829d590b04165bc 100644 (file)
@@ -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>();
 }
index 3c69f236755a919062276a8c1af4a4334a8f44ae..8c1d2bbfeef49b6d4d7cda3981b35872ce0ee04c 100644 (file)
@@ -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 }