[libcxx-commits] [libcxx] [libc++][valarray] Applied `[[nodiscard]]` (PR #170996)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Sat Dec 6 13:40:51 PST 2025


https://github.com/H-G-Hristov created https://github.com/llvm/llvm-project/pull/170996

`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.

- https://libcxx.llvm.org/CodingGuidelines.html

>From 9b2770aa6c11a182194455759a07e2840b0ae79c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 6 Dec 2025 23:40:15 +0200
Subject: [PATCH] [libc++][valarray] Applied `[[nodiscard]]`

`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.

- https://libcxx.llvm.org/CodingGuidelines.html
---
 libcxx/include/valarray                       | 105 +++++++++---------
 .../numerics/numarray/nodiscard.verify.cpp    |  96 ++++++++++++++++
 2 files changed, 151 insertions(+), 50 deletions(-)
 create mode 100644 libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp

diff --git a/libcxx/include/valarray b/libcxx/include/valarray
index 215811d5ba475..5df49fb442132 100644
--- a/libcxx/include/valarray
+++ b/libcxx/include/valarray
@@ -396,9 +396,9 @@ public:
   _LIBCPP_HIDE_FROM_ABI slice(size_t __start, size_t __size, size_t __stride)
       : __start_(__start), __size_(__size), __stride_(__stride) {}
 
-  _LIBCPP_HIDE_FROM_ABI size_t start() const { return __start_; }
-  _LIBCPP_HIDE_FROM_ABI size_t size() const { return __size_; }
-  _LIBCPP_HIDE_FROM_ABI size_t stride() const { return __stride_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t start() const { return __start_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t size() const { return __size_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t stride() const { return __stride_; }
 
 #  if _LIBCPP_STD_VER >= 20
 
@@ -822,36 +822,41 @@ public:
   _LIBCPP_HIDE_FROM_ABI valarray& operator=(const __val_expr<_ValExpr>& __v);
 
   // element access:
-  _LIBCPP_HIDE_FROM_ABI const value_type& operator[](size_t __i) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const value_type& operator[](size_t __i) const {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "valarray::operator[] index out of bounds");
     return __begin_[__i];
   }
 
-  _LIBCPP_HIDE_FROM_ABI value_type& operator[](size_t __i) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type& operator[](size_t __i) {
     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "valarray::operator[] index out of bounds");
     return __begin_[__i];
   }
 
   // subset operations:
-  _LIBCPP_HIDE_FROM_ABI __val_expr<__slice_expr<const valarray&> > operator[](slice __s) const;
-  _LIBCPP_HIDE_FROM_ABI slice_array<value_type> operator[](slice __s);
-  _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](const gslice& __gs) const;
-  _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](const gslice& __gs);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__slice_expr<const valarray&> > operator[](slice __s) const;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI slice_array<value_type> operator[](slice __s);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> >
+  operator[](const gslice& __gs) const;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](const gslice& __gs);
 #  ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
-  _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](gslice&& __gs);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI gslice_array<value_type> operator[](gslice&& __gs);
 #  endif // _LIBCPP_CXX03_LANG
+  [[__nodiscard__]]
   _LIBCPP_HIDE_FROM_ABI __val_expr<__mask_expr<const valarray&> > operator[](const valarray<bool>& __vb) const;
-  _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](const valarray<bool>& __vb);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](const valarray<bool>& __vb);
 #  ifndef _LIBCPP_CXX03_LANG
+  [[__nodiscard__]]
   _LIBCPP_HIDE_FROM_ABI __val_expr<__mask_expr<const valarray&> > operator[](valarray<bool>&& __vb) const;
-  _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](valarray<bool>&& __vb);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mask_array<value_type> operator[](valarray<bool>&& __vb);
 #  endif // _LIBCPP_CXX03_LANG
+  [[__nodiscard__]]
   _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](const valarray<size_t>& __vs) const;
-  _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](const valarray<size_t>& __vs);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](const valarray<size_t>& __vs);
 #  ifndef _LIBCPP_CXX03_LANG
+  [[__nodiscard__]]
   _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr<const valarray&> > operator[](valarray<size_t>&& __vs) const;
-  _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](valarray<size_t>&& __vs);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI indirect_array<value_type> operator[](valarray<size_t>&& __vs);
 #  endif // _LIBCPP_CXX03_LANG
 
   // unary operators:
@@ -905,16 +910,16 @@ public:
   // member functions:
   _LIBCPP_HIDE_FROM_ABI void swap(valarray& __v) _NOEXCEPT;
 
-  _LIBCPP_HIDE_FROM_ABI size_t size() const { return static_cast<size_t>(__end_ - __begin_); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t size() const { return static_cast<size_t>(__end_ - __begin_); }
 
-  _LIBCPP_HIDE_FROM_ABI value_type sum() const;
-  _LIBCPP_HIDE_FROM_ABI value_type min() const;
-  _LIBCPP_HIDE_FROM_ABI value_type max() const;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type sum() const;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type min() const;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_type max() const;
 
-  valarray shift(int __i) const;
-  valarray cshift(int __i) const;
-  valarray apply(value_type __f(value_type)) const;
-  valarray apply(value_type __f(const value_type&)) const;
+  [[__nodiscard__]] valarray shift(int __i) const;
+  [[__nodiscard__]] valarray cshift(int __i) const;
+  [[__nodiscard__]] valarray apply(value_type __f(value_type)) const;
+  [[__nodiscard__]] valarray apply(value_type __f(const value_type&)) const;
   void resize(size_t __n, value_type __x = value_type());
 
 private:
@@ -1249,11 +1254,11 @@ public:
 
 #  endif // _LIBCPP_CXX03_LANG
 
-  _LIBCPP_HIDE_FROM_ABI size_t start() const { return __1d_.size() ? __1d_[0] : 0; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t start() const { return __1d_.size() ? __1d_[0] : 0; }
 
-  _LIBCPP_HIDE_FROM_ABI valarray<size_t> size() const { return __size_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI valarray<size_t> size() const { return __size_; }
 
-  _LIBCPP_HIDE_FROM_ABI valarray<size_t> stride() const { return __stride_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI valarray<size_t> stride() const { return __stride_; }
 
 private:
   void __init(size_t __start);
@@ -3106,7 +3111,7 @@ operator>=(const typename _Expr::value_type& __x, const _Expr& __y) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
 abs(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__abs_expr<value_type>, _Expr> _Op;
@@ -3114,7 +3119,7 @@ abs(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
 acos(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__acos_expr<value_type>, _Expr> _Op;
@@ -3122,7 +3127,7 @@ acos(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
 asin(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__asin_expr<value_type>, _Expr> _Op;
@@ -3130,7 +3135,7 @@ asin(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
 atan(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__atan_expr<value_type>, _Expr> _Op;
@@ -3140,7 +3145,7 @@ atan(const _Expr& __x) {
 template <class _Expr1,
           class _Expr2,
           __enable_if_t<__is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
 atan2(const _Expr1& __x, const _Expr2& __y) {
   typedef typename _Expr1::value_type value_type;
   typedef _BinaryOp<__atan2_expr<value_type>, _Expr1, _Expr2> _Op;
@@ -3148,7 +3153,7 @@ atan2(const _Expr1& __x, const _Expr2& __y) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>, _Expr, __scalar_expr<typename _Expr::value_type> > >
 atan2(const _Expr& __x, const typename _Expr::value_type& __y) {
   typedef typename _Expr::value_type value_type;
@@ -3157,7 +3162,7 @@ atan2(const _Expr& __x, const typename _Expr::value_type& __y) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>, __scalar_expr<typename _Expr::value_type>, _Expr> >
 atan2(const typename _Expr::value_type& __x, const _Expr& __y) {
   typedef typename _Expr::value_type value_type;
@@ -3166,7 +3171,7 @@ atan2(const typename _Expr::value_type& __x, const _Expr& __y) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
 cos(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__cos_expr<value_type>, _Expr> _Op;
@@ -3174,7 +3179,7 @@ cos(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
 cosh(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__cosh_expr<value_type>, _Expr> _Op;
@@ -3182,7 +3187,7 @@ cosh(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
 exp(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__exp_expr<value_type>, _Expr> _Op;
@@ -3190,7 +3195,7 @@ exp(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
 log(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__log_expr<value_type>, _Expr> _Op;
@@ -3198,7 +3203,7 @@ log(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
 log10(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__log10_expr<value_type>, _Expr> _Op;
@@ -3208,7 +3213,7 @@ log10(const _Expr& __x) {
 template <class _Expr1,
           class _Expr2,
           __enable_if_t<__is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
 pow(const _Expr1& __x, const _Expr2& __y) {
   typedef typename _Expr1::value_type value_type;
   typedef _BinaryOp<__pow_expr<value_type>, _Expr1, _Expr2> _Op;
@@ -3216,7 +3221,7 @@ pow(const _Expr1& __x, const _Expr2& __y) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>, _Expr, __scalar_expr<typename _Expr::value_type> > >
 pow(const _Expr& __x, const typename _Expr::value_type& __y) {
   typedef typename _Expr::value_type value_type;
@@ -3225,7 +3230,7 @@ pow(const _Expr& __x, const typename _Expr::value_type& __y) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
 __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>, __scalar_expr<typename _Expr::value_type>, _Expr> >
 pow(const typename _Expr::value_type& __x, const _Expr& __y) {
   typedef typename _Expr::value_type value_type;
@@ -3234,7 +3239,7 @@ pow(const typename _Expr::value_type& __x, const _Expr& __y) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
 sin(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__sin_expr<value_type>, _Expr> _Op;
@@ -3242,7 +3247,7 @@ sin(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
 sinh(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__sinh_expr<value_type>, _Expr> _Op;
@@ -3250,7 +3255,7 @@ sinh(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
 sqrt(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__sqrt_expr<value_type>, _Expr> _Op;
@@ -3258,7 +3263,7 @@ sqrt(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
 tan(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__tan_expr<value_type>, _Expr> _Op;
@@ -3266,7 +3271,7 @@ tan(const _Expr& __x) {
 }
 
 template <class _Expr, __enable_if_t<__is_val_expr<_Expr>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
 tanh(const _Expr& __x) {
   typedef typename _Expr::value_type value_type;
   typedef _UnaryOp<__tanh_expr<value_type>, _Expr> _Op;
@@ -3274,22 +3279,22 @@ tanh(const _Expr& __x) {
 }
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _Tp* begin(valarray<_Tp>& __v) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp* begin(valarray<_Tp>& __v) {
   return __v.__begin_;
 }
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI const _Tp* begin(const valarray<_Tp>& __v) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI const _Tp* begin(const valarray<_Tp>& __v) {
   return __v.__begin_;
 }
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _Tp* end(valarray<_Tp>& __v) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp* end(valarray<_Tp>& __v) {
   return __v.__end_;
 }
 
 template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI const _Tp* end(const valarray<_Tp>& __v) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI const _Tp* end(const valarray<_Tp>& __v) {
   return __v.__end_;
 }
 
diff --git a/libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp b/libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..84e810f6dfe25
--- /dev/null
+++ b/libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp
@@ -0,0 +1,96 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <valarray>
+#include <utility>
+
+#include "test_macros.h"
+
+int func(int);
+
+int cfunc(const int&);
+
+void test() {
+  std::slice s;
+
+  s.size();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  s.start();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  s.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  std::gslice gs;
+
+  std::valarray<int> va;
+  const std::valarray<int> cva;
+
+  std::valarray<bool> bva;
+  std::valarray<std::size_t> sva;
+
+  cva[0];   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va[0];    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cva[s];   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va[s];    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cva[gs];  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va[gs];   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cva[bva]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va[bva];  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 11
+  cva[std::move(bva)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cva[std::move(bva)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+  cva[sva]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va[sva];  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 11
+  cva[std::move(sva)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cva[std::move(sva)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+  va.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  va.sum(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va.min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va.max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  va.shift(1);     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va.cshift(1);    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va.apply(func);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va.apply(cfunc); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  gs.size();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  gs.start();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  gs.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  std::abs(va);       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::acos(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::asin(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::atan(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::atan2(va, va); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::atan2(va, 94); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::atan2(82, va); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::cos(va);       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::cosh(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::exp(va);       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::log(va);       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::log10(va);     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::pow(va, va);   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::pow(va, 94);   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::pow(82, va);   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::sin(va);       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::sinh(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::sqrt(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::tan(va);       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::tanh(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+  std::begin(va);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::begin(cva); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::end(va);    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::end(cva);   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}



More information about the libcxx-commits mailing list