diff --git a/libcxx/include/valarray b/libcxx/include/valarray index 215811d5ba475..f04923d08c269 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 > operator[](slice __s) const; - _LIBCPP_HIDE_FROM_ABI slice_array operator[](slice __s); - _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr > operator[](const gslice& __gs) const; - _LIBCPP_HIDE_FROM_ABI gslice_array operator[](const gslice& __gs); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__slice_expr > operator[](slice __s) const; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI slice_array operator[](slice __s); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr > + operator[](const gslice& __gs) const; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI gslice_array operator[](const gslice& __gs); # ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr > operator[](gslice&& __gs) const; - _LIBCPP_HIDE_FROM_ABI gslice_array operator[](gslice&& __gs); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr > operator[](gslice&& __gs) const; + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI gslice_array operator[](gslice&& __gs); # endif // _LIBCPP_CXX03_LANG + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__mask_expr > operator[](const valarray& __vb) const; - _LIBCPP_HIDE_FROM_ABI mask_array operator[](const valarray& __vb); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mask_array operator[](const valarray& __vb); # ifndef _LIBCPP_CXX03_LANG + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__mask_expr > operator[](valarray&& __vb) const; - _LIBCPP_HIDE_FROM_ABI mask_array operator[](valarray&& __vb); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mask_array operator[](valarray&& __vb); # endif // _LIBCPP_CXX03_LANG + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr > operator[](const valarray& __vs) const; - _LIBCPP_HIDE_FROM_ABI indirect_array operator[](const valarray& __vs); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI indirect_array operator[](const valarray& __vs); # ifndef _LIBCPP_CXX03_LANG + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __val_expr<__indirect_expr > operator[](valarray&& __vs) const; - _LIBCPP_HIDE_FROM_ABI indirect_array operator[](valarray&& __vs); + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI indirect_array operator[](valarray&& __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(__end_ - __begin_); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t size() const { return static_cast(__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() const { return __size_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI valarray size() const { return __size_; } - _LIBCPP_HIDE_FROM_ABI valarray stride() const { return __stride_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI valarray 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 ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__abs_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__abs_expr, _Expr> > abs(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__abs_expr, _Expr> _Op; @@ -3114,7 +3119,7 @@ abs(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__acos_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__acos_expr, _Expr> > acos(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__acos_expr, _Expr> _Op; @@ -3122,7 +3127,7 @@ acos(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__asin_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__asin_expr, _Expr> > asin(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__asin_expr, _Expr> _Op; @@ -3130,7 +3135,7 @@ asin(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__atan_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__atan_expr, _Expr> > atan(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__atan_expr, _Expr> _Op; @@ -3140,15 +3145,16 @@ atan(const _Expr& __x) { template ::value && __is_val_expr<_Expr2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr, _Expr1, _Expr2> > -atan2(const _Expr1& __x, const _Expr2& __y) { +[[__nodiscard__]] inline + _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr, _Expr1, _Expr2> > + atan2(const _Expr1& __x, const _Expr2& __y) { typedef typename _Expr1::value_type value_type; typedef _BinaryOp<__atan2_expr, _Expr1, _Expr2> _Op; return __val_expr<_Op>(_Op(__atan2_expr(), __x, __y)); } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr, _Expr, __scalar_expr > > atan2(const _Expr& __x, const typename _Expr::value_type& __y) { typedef typename _Expr::value_type value_type; @@ -3157,7 +3163,7 @@ atan2(const _Expr& __x, const typename _Expr::value_type& __y) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__atan2_expr, __scalar_expr, _Expr> > atan2(const typename _Expr::value_type& __x, const _Expr& __y) { typedef typename _Expr::value_type value_type; @@ -3166,7 +3172,7 @@ atan2(const typename _Expr::value_type& __x, const _Expr& __y) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cos_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cos_expr, _Expr> > cos(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__cos_expr, _Expr> _Op; @@ -3174,7 +3180,7 @@ cos(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cosh_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__cosh_expr, _Expr> > cosh(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__cosh_expr, _Expr> _Op; @@ -3182,7 +3188,7 @@ cosh(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__exp_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__exp_expr, _Expr> > exp(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__exp_expr, _Expr> _Op; @@ -3190,7 +3196,7 @@ exp(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log_expr, _Expr> > log(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__log_expr, _Expr> _Op; @@ -3198,7 +3204,7 @@ log(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log10_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__log10_expr, _Expr> > log10(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__log10_expr, _Expr> _Op; @@ -3208,15 +3214,16 @@ log10(const _Expr& __x) { template ::value && __is_val_expr<_Expr2>::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr, _Expr1, _Expr2> > -pow(const _Expr1& __x, const _Expr2& __y) { +[[__nodiscard__]] inline + _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr, _Expr1, _Expr2> > + pow(const _Expr1& __x, const _Expr2& __y) { typedef typename _Expr1::value_type value_type; typedef _BinaryOp<__pow_expr, _Expr1, _Expr2> _Op; return __val_expr<_Op>(_Op(__pow_expr(), __x, __y)); } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr, _Expr, __scalar_expr > > pow(const _Expr& __x, const typename _Expr::value_type& __y) { typedef typename _Expr::value_type value_type; @@ -3225,7 +3232,7 @@ pow(const _Expr& __x, const typename _Expr::value_type& __y) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_BinaryOp<__pow_expr, __scalar_expr, _Expr> > pow(const typename _Expr::value_type& __x, const _Expr& __y) { typedef typename _Expr::value_type value_type; @@ -3234,7 +3241,7 @@ pow(const typename _Expr::value_type& __x, const _Expr& __y) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sin_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sin_expr, _Expr> > sin(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__sin_expr, _Expr> _Op; @@ -3242,7 +3249,7 @@ sin(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sinh_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sinh_expr, _Expr> > sinh(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__sinh_expr, _Expr> _Op; @@ -3250,7 +3257,7 @@ sinh(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sqrt_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__sqrt_expr, _Expr> > sqrt(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__sqrt_expr, _Expr> _Op; @@ -3258,7 +3265,7 @@ sqrt(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tan_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tan_expr, _Expr> > tan(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__tan_expr, _Expr> _Op; @@ -3266,7 +3273,7 @@ tan(const _Expr& __x) { } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tanh_expr, _Expr> > +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI __val_expr<_UnaryOp<__tanh_expr, _Expr> > tanh(const _Expr& __x) { typedef typename _Expr::value_type value_type; typedef _UnaryOp<__tanh_expr, _Expr> _Op; @@ -3274,22 +3281,22 @@ tanh(const _Expr& __x) { } template -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 -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 -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 -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 +// +//===----------------------------------------------------------------------===// + +// + +// Check that functions are marked [[nodiscard]] + +#include +#include + +#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 va; + const std::valarray cva; + + std::valarray bva; + std::valarray 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}} +}