[v2] libstdc++: Add more nodiscard uses in <vector>

Message ID CACb0b4kFoa8yGqH86oOOOYaW4AMDDk7rXhQVmaSjCTrad0VUwQ@mail.gmail.com
State Unresolved
Headers
Series [v2] libstdc++: Add more nodiscard uses in <vector> |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Jonathan Wakely Feb. 29, 2024, 12:28 p.m. UTC
  We need to add [[nodiscard]] to the comparison ops in <debug/vector>
too, which I missed in the v1 patch.

Tested aarch64-linux. Pushed to trunk (yesterday).
commit 26d6a714b29eeef77591f136f5162622a549d8fd
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Feb 26 13:09:02 2024

    libstdc++: Add more nodiscard uses in <vector>
    
    Add [[nodiscard]] to vector::at and to comparison operators.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/stl_bvector.h (vector<bool, A>::at): Add
            nodiscard.
            * include/bits/stl_vector.h (vector<T, A>::at): Likewise.
            (operator==, operator<=>, operator<, operator!=, operator>)
            (operator<=, operator>=): Likewise.
            * include/debug/vector (operator==, operator<=>, operator<)
            (operator!=, operator>, operator<=, operator>=): Likewise.
            * testsuite/23_containers/vector/nodiscard.cc: New test.
  

Patch

diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index aa5644b4a0e..2c8b892b07a 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1101,7 +1101,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       }
 
     public:
-      _GLIBCXX20_CONSTEXPR
+      _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
       reference
       at(size_type __n)
       {
@@ -1109,7 +1109,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	return (*this)[__n];
       }
 
-      _GLIBCXX20_CONSTEXPR
+      _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
       const_reference
       at(size_type __n) const
       {
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 6a9543eefce..a8d387f40a1 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1172,7 +1172,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  is first checked that it is in the range of the vector.  The
        *  function throws out_of_range if the check fails.
        */
-      _GLIBCXX20_CONSTEXPR
+      _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
       reference
       at(size_type __n)
       {
@@ -1191,7 +1191,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  is first checked that it is in the range of the vector.  The
        *  function throws out_of_range if the check fails.
        */
-      _GLIBCXX20_CONSTEXPR
+      _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
       const_reference
       at(size_type __n) const
       {
@@ -2042,7 +2042,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  and if corresponding elements compare equal.
   */
   template<typename _Tp, typename _Alloc>
-    _GLIBCXX20_CONSTEXPR
+    _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
     inline bool
     operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     { return (__x.size() == __y.size()
@@ -2061,7 +2061,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  `<` and `>=` etc.
   */
   template<typename _Tp, typename _Alloc>
-    _GLIBCXX20_CONSTEXPR
+    [[nodiscard]] _GLIBCXX20_CONSTEXPR
     inline __detail::__synth3way_t<_Tp>
     operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     {
@@ -2082,32 +2082,32 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  See std::lexicographical_compare() for how the determination is made.
   */
   template<typename _Tp, typename _Alloc>
-    inline bool
+    _GLIBCXX_NODISCARD inline bool
     operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     { return std::lexicographical_compare(__x.begin(), __x.end(),
 					  __y.begin(), __y.end()); }
 
   /// Based on operator==
   template<typename _Tp, typename _Alloc>
-    inline bool
+    _GLIBCXX_NODISCARD inline bool
     operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     { return !(__x == __y); }
 
   /// Based on operator<
   template<typename _Tp, typename _Alloc>
-    inline bool
+    _GLIBCXX_NODISCARD inline bool
     operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     { return __y < __x; }
 
   /// Based on operator<
   template<typename _Tp, typename _Alloc>
-    inline bool
+    _GLIBCXX_NODISCARD inline bool
     operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     { return !(__y < __x); }
 
   /// Based on operator<
   template<typename _Tp, typename _Alloc>
-    inline bool
+    _GLIBCXX_NODISCARD inline bool
     operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     { return !(__x < __y); }
 #endif // three-way comparison
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 5a0fc808651..216822975a2 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -866,7 +866,7 @@  namespace __debug
     };
 
   template<typename _Tp, typename _Alloc>
-    _GLIBCXX20_CONSTEXPR
+    _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
     inline bool
     operator==(const vector<_Tp, _Alloc>& __lhs,
 	       const vector<_Tp, _Alloc>& __rhs)
@@ -874,35 +874,41 @@  namespace __debug
 
 #if __cpp_lib_three_way_comparison
   template<typename _Tp, typename _Alloc>
+    [[nodiscard]]
     constexpr __detail::__synth3way_t<_Tp>
     operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     { return __x._M_base() <=> __y._M_base(); }
 #else
   template<typename _Tp, typename _Alloc>
+    _GLIBCXX_NODISCARD
     inline bool
     operator!=(const vector<_Tp, _Alloc>& __lhs,
 	       const vector<_Tp, _Alloc>& __rhs)
     { return __lhs._M_base() != __rhs._M_base(); }
 
   template<typename _Tp, typename _Alloc>
+    _GLIBCXX_NODISCARD
     inline bool
     operator<(const vector<_Tp, _Alloc>& __lhs,
 	      const vector<_Tp, _Alloc>& __rhs)
     { return __lhs._M_base() < __rhs._M_base(); }
 
   template<typename _Tp, typename _Alloc>
+    _GLIBCXX_NODISCARD
     inline bool
     operator<=(const vector<_Tp, _Alloc>& __lhs,
 	       const vector<_Tp, _Alloc>& __rhs)
     { return __lhs._M_base() <= __rhs._M_base(); }
 
   template<typename _Tp, typename _Alloc>
+    _GLIBCXX_NODISCARD
     inline bool
     operator>=(const vector<_Tp, _Alloc>& __lhs,
 	       const vector<_Tp, _Alloc>& __rhs)
     { return __lhs._M_base() >= __rhs._M_base(); }
 
   template<typename _Tp, typename _Alloc>
+    _GLIBCXX_NODISCARD
     inline bool
     operator>(const vector<_Tp, _Alloc>& __lhs,
 	      const vector<_Tp, _Alloc>& __rhs)
diff --git a/libstdc++-v3/testsuite/23_containers/vector/nodiscard.cc b/libstdc++-v3/testsuite/23_containers/vector/nodiscard.cc
new file mode 100644
index 00000000000..3b5480d16d4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/nodiscard.cc
@@ -0,0 +1,153 @@ 
+// { dg-do compile { target c++17 } }
+
+#include <vector>
+
+void
+test_observers(std::vector<int> v)
+{
+  v.size(); // { dg-warning "ignoring return value" }
+  v.capacity(); // { dg-warning "ignoring return value" }
+  v.empty(); // { dg-warning "ignoring return value" }
+}
+
+void
+test_element_access(std::vector<float> v)
+{
+  v.front(); // { dg-warning "ignoring return value" }
+  v.back();  // { dg-warning "ignoring return value" }
+  v[1];      // { dg-warning "ignoring return value" }
+  v.at(1);   // { dg-warning "ignoring return value" }
+  v.data();  // { dg-warning "ignoring return value" }
+  const auto& cv = v;
+  cv[1];     // { dg-warning "ignoring return value" }
+  cv.at(1);  // { dg-warning "ignoring return value" }
+  cv.data(); // { dg-warning "ignoring return value" }
+}
+
+void
+test_rel_ops(std::vector<char> v)
+{
+  v == v; // { dg-warning "ignoring return value" }
+  v != v; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  v < v;  // { dg-warning "ignoring return value" }
+  v > v;  // { dg-warning "ignoring return value" }
+  v <= v; // { dg-warning "ignoring return value" }
+  v >= v; // { dg-warning "ignoring return value" }
+}
+
+struct S { };
+
+void
+test_iterators(std::vector<S> v)
+{
+  v.begin();  // { dg-warning "ignoring return value" }
+  v.end();    // { dg-warning "ignoring return value" }
+  v.rbegin(); // { dg-warning "ignoring return value" }
+  v.rend();   // { dg-warning "ignoring return value" }
+  const auto& cv = v;
+  cv.begin();  // { dg-warning "ignoring return value" }
+  cv.end();    // { dg-warning "ignoring return value" }
+  cv.rbegin(); // { dg-warning "ignoring return value" }
+  cv.rend();   // { dg-warning "ignoring return value" }
+
+  v.cbegin();  // { dg-warning "ignoring return value" }
+  v.cend();    // { dg-warning "ignoring return value" }
+  v.crbegin(); // { dg-warning "ignoring return value" }
+  v.crend();   // { dg-warning "ignoring return value" }
+
+  auto i = v.begin(), j = v.end();
+  i == j; // { dg-warning "ignoring return value" }
+  i != j; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  i < j;  // { dg-warning "ignoring return value" }
+  i > j;  // { dg-warning "ignoring return value" }
+  i <= j; // { dg-warning "ignoring return value" }
+  i >= j; // { dg-warning "ignoring return value" }
+
+  auto ci = cv.begin(), cj = cv.end();
+  ci == cj; // { dg-warning "ignoring return value" }
+  ci != cj; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  ci < cj;  // { dg-warning "ignoring return value" }
+  ci > cj;  // { dg-warning "ignoring return value" }
+  ci <= cj; // { dg-warning "ignoring return value" }
+  ci >= cj; // { dg-warning "ignoring return value" }
+
+  ci == j; // { dg-warning "ignoring return value" }
+  ci != j; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  ci < j;  // { dg-warning "ignoring return value" }
+  ci > j;  // { dg-warning "ignoring return value" }
+  ci <= j; // { dg-warning "ignoring return value" }
+  ci >= j; // { dg-warning "ignoring return value" }
+}
+
+void
+test_observers(std::vector<bool> v)
+{
+  v.size(); // { dg-warning "ignoring return value" }
+  v.capacity(); // { dg-warning "ignoring return value" }
+  v.empty(); // { dg-warning "ignoring return value" }
+}
+
+void
+test_element_access(std::vector<bool> v)
+{
+  v.front(); // { dg-warning "ignoring return value" }
+  v.back();  // { dg-warning "ignoring return value" }
+  v[1];      // { dg-warning "ignoring return value" }
+  v.at(1);   // { dg-warning "ignoring return value" }
+  const auto& cv = v;
+  cv[1];     // { dg-warning "ignoring return value" }
+  cv.at(1);  // { dg-warning "ignoring return value" }
+}
+
+void
+test_rel_ops(std::vector<bool> v)
+{
+  v == v; // { dg-warning "ignoring return value" }
+  v != v; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  v < v;  // { dg-warning "ignoring return value" }
+  v > v;  // { dg-warning "ignoring return value" }
+  v <= v; // { dg-warning "ignoring return value" }
+  v >= v; // { dg-warning "ignoring return value" }
+}
+
+void
+test_iterators(std::vector<bool> v)
+{
+  v.begin();  // { dg-warning "ignoring return value" }
+  v.end();    // { dg-warning "ignoring return value" }
+  v.rbegin(); // { dg-warning "ignoring return value" }
+  v.rend();   // { dg-warning "ignoring return value" }
+  const auto& cv = v;
+  cv.begin();  // { dg-warning "ignoring return value" }
+  cv.end();    // { dg-warning "ignoring return value" }
+  cv.rbegin(); // { dg-warning "ignoring return value" }
+  cv.rend();   // { dg-warning "ignoring return value" }
+
+  v.cbegin();  // { dg-warning "ignoring return value" }
+  v.cend();    // { dg-warning "ignoring return value" }
+  v.crbegin(); // { dg-warning "ignoring return value" }
+  v.crend();   // { dg-warning "ignoring return value" }
+
+  auto i = v.begin(), j = v.end();
+  i == j; // { dg-warning "ignoring return value" }
+  i != j; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  i < j;  // { dg-warning "ignoring return value" }
+  i > j;  // { dg-warning "ignoring return value" }
+  i <= j; // { dg-warning "ignoring return value" }
+  i >= j; // { dg-warning "ignoring return value" }
+
+  auto ci = cv.begin(), cj = cv.end();
+  ci == cj; // { dg-warning "ignoring return value" }
+  ci != cj; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  ci < cj;  // { dg-warning "ignoring return value" }
+  ci > cj;  // { dg-warning "ignoring return value" }
+  ci <= cj; // { dg-warning "ignoring return value" }
+  ci >= cj; // { dg-warning "ignoring return value" }
+
+  ci == j; // { dg-warning "ignoring return value" }
+  ci != j; // { dg-warning "ignoring return value" "PR c++/114104" { target c++17_down } }
+  ci < j;  // { dg-warning "ignoring return value" }
+  ci > j;  // { dg-warning "ignoring return value" }
+  ci <= j; // { dg-warning "ignoring return value" }
+  ci >= j; // { dg-warning "ignoring return value" }
+}