]> 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>
Tue, 12 Mar 2024 11:53:05 +0000 (11:53 +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.

(cherry picked from commit a92a434024c59f57dc24328d946f97a5e71cee94)

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 6763389966503113f41fb9bcc545f34a9d474b17..b70893779d843079c15c316b5bf18c46fcbfc25a 100644 (file)
@@ -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<size_t _Count>
+       [[nodiscard]]
        constexpr span<element_type, _Count>
        first() const noexcept
        {
@@ -337,6 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          return _Sp{ this->data(), _Count };
        }
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       first(size_type __count) const noexcept
       {
@@ -345,6 +362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       template<size_t _Count>
+       [[nodiscard]]
        constexpr span<element_type, _Count>
        last() const noexcept
        {
@@ -356,6 +374,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
       {
@@ -364,6 +383,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>()>
@@ -395,6 +415,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            }
        }
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       subspan(size_type __offset, size_type __count = dynamic_extent) const
       noexcept
@@ -436,6 +457,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)>
@@ -453,7 +475,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 2b4dee6df9acc031a79d9a0317e530d0c9ca33a8..a7048977f473dc08aa3b060bc83a66b883a8d6d5 100644 (file)
@@ -26,5 +26,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s.back();
+  (void) s.back();
 }
index 01083e601688257dcf1034a73eeeb0c6f88e0212..8c252a7ea6984ab18fd302f8c3f6e4fa56fe2c8d 100644 (file)
@@ -25,7 +25,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s.back();
+    (void) s.back();
   return true;
 }
 
index 93cd095495a03d3f68509256c4810886c540445f..4220a6bca0e9fe800e52428fe4afb17e2747fb11 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.first(5);
+  (void) s.first(5);
 }
index 4ff56bf65cfff005e2182b7153a8dea5606fb645..26c6483f1d7242dd3c2ebf7793742f78358ef707 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.first<5>();
+  (void) s.first<5>();
 }
index 8ed68296263bfad091370a0659c5e8344b8a2948..790107017275678ca6dad63609ead620ab73a6d7 100644 (file)
@@ -25,6 +25,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 2d4320d0fd98f4298dd0c522a363b1c9093f8889..e1b1ad3287ec4e7da707d124a14d5d808aab67f9 100644 (file)
@@ -26,5 +26,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s.front();
+  (void) s.front();
 }
index f8e8100bd7cba7c8df7885d930e73191ec50a490..8e688d30fd326971424313b527e03738fe434734 100644 (file)
@@ -25,7 +25,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s.front();
+    (void) s.front();
   return true;
 }
 
index b2633cbfaabd0ac9e7e8d4e50abdefaeaec9c9a4..8a7ef3d14642cc38041b1df22778ef01e0c88cad 100644 (file)
@@ -26,5 +26,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s[99];
+  (void) s[99];
 }
index 8bbe8ea0737503db05d2107820b9dda6ec5e9f98..810a7c2aa238125e48f9d0bf9258f89ac055d5ab 100644 (file)
@@ -25,7 +25,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s[99];
+    (void) s[99];
   return true;
 }
 
index 906896911c0f2be1894739b8589b99dd421e3626..6046264593b467047ad6314f71a586ed059a395f 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.last(5);
+  (void) s.last(5);
 }
index 59cd44acc3cf965be111708ef7b40a97e4d77b15..a1a4def2b8b0edec5baa728cf7bd871c1288f119 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.last<5>();
+  (void) s.last<5>();
 }
index 9c360d2650ef5fbd16112fc60ca33d866ffff61b..dc2e99ad0fd5cc519805678e637e0ce1ba6aa588 100644 (file)
@@ -25,6 +25,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 488b56069936d3bace6630694d3cefe2b91fac3c..b047cbe57b4c4e3704b2582cb2d01bc7fc8ad6bf 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan<2, 5>();
+  (void) s.subspan<2, 5>();
 }
index 8324edfc49a774ee6db506b820336378c110d294..154e5874449429a4a20e0e115f06b5f7dfbcea6f 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan<2, 3>();
+  (void) s.subspan<2, 3>();
 }
index b1dbfe6902e7519927e4b427d8674cb63fcd79b5..1757c4efaedf3b10767facdcf4bb54aa21fb2244 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan(5, 0);
+  (void) s.subspan(5, 0);
 }
index 2102fd02cce50b1ae0f3353eddf678a4bfc388f5..d327f557c22b858531b95e7c87daae7897eca9cb 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan(2, 5);
+  (void) s.subspan(2, 5);
 }
index c003561032c286f491d91ac7a2dc60e8ab6c4e31..a4227948f552fa8af9dd794c385b271fd0b1d0e2 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan(2, 3);
+  (void) s.subspan(2, 3);
 }
index c46b78fe8bc6cf25663c45bf7ad40be5cf653e27..1b4b63a22affb2cb7e5dbd23b18e9f38fe723475 100644 (file)
@@ -27,5 +27,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan<5, 0>();
+  (void) s.subspan<5, 0>();
 }
index 205bafd39ddc184e07e445ba782bb82376541106..4ff764a37247601207c954423e2fab7efaec5c13 100644 (file)
@@ -25,7 +25,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
@@ -33,7 +33,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
@@ -41,7 +41,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 }