From 5cbfae59f378a9eaa98ea834c2e8e1be521be9eb Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Thu, 20 Nov 2025 07:59:03 +0200 Subject: [PATCH 1/7] [libc++][array] 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#apply-nodiscard-where-relevant --- libcxx/include/array | 145 +++++++++++------- .../diagnostics/array.nodiscard.verify.cpp | 91 ++++++++++- .../array/array.creation/to_array.verify.cpp | 20 ++- 3 files changed, 188 insertions(+), 68 deletions(-) diff --git a/libcxx/include/array b/libcxx/include/array index ff46838e2e8e2..d346b50cfcd7a 100644 --- a/libcxx/include/array +++ b/libcxx/include/array @@ -210,28 +210,28 @@ struct array { } // iterators: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data(), data()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data(), data()); # else return const_iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data() + _Size, data()); # else return iterator(data() + _Size); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<_Size>(data() + _Size, data()); # else @@ -239,62 +239,81 @@ struct array { # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { + return begin(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { + return end(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + crbegin() const _NOEXCEPT { return rbegin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { + return rend(); + } // capacity: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; } [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return _Size == 0; } // element access: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type __n) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference + operator[](size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) { if (__n >= _Size) std::__throw_out_of_range("array::at"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const { if (__n >= _Size) std::__throw_out_of_range("array::at"); return __elems_[__n]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { return (*this)[0]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { return (*this)[0]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { return (*this)[_Size - 1]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { + return (*this)[0]; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { + return (*this)[0]; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { + return (*this)[_Size - 1]; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { return (*this)[_Size - 1]; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return __elems_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return __elems_; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { + return __elems_; + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { + return __elems_; + } }; template @@ -328,8 +347,10 @@ struct array<_Tp, 0> { }; _ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)]; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return nullptr; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { + return nullptr; + } // No explicit construct/copy/destroy for aggregate type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type&) { @@ -341,28 +362,28 @@ struct array<_Tp, 0> { } // iterators: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else return const_iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) return std::__make_static_bounded_iter<0>(data(), data()); # else @@ -370,68 +391,77 @@ struct array<_Tp, 0> { # endif } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { + return begin(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { + return end(); + } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator + crbegin() const _NOEXCEPT { return rbegin(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { + return rend(); + } // capacity: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; } + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; } [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return true; } // element access: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array::operator[] on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type) const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference + operator[](size_type) const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array::operator[] on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) { std::__throw_out_of_range("array::at"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const { std::__throw_out_of_range("array::at"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array::front() on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array::front() on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array::back() on a zero-sized array"); __libcpp_unreachable(); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array::back() on a zero-sized array"); __libcpp_unreachable(); } @@ -443,8 +473,8 @@ array(_Tp, _Args...) -> array<_Tp, 1 + sizeof...(_Args)>; # endif template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return std::equal(__x.begin(), __x.end(), __y.begin()); } @@ -501,25 +531,28 @@ struct tuple_element<_Ip, array<_Tp, _Size> > { }; template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& +get(array<_Tp, _Size>& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)"); return __a.__elems_[_Ip]; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +get(const array<_Tp, _Size>& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)"); return __a.__elems_[_Ip]; } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); return std::move(__a.__elems_[_Ip]); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& +get(const array<_Tp, _Size>&& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)"); return std::move(__a.__elems_[_Ip]); } @@ -539,7 +572,7 @@ __to_array_rvalue_impl(_Tp (&&__arr)[_Size], index_sequence<_Index...>) { } template -_LIBCPP_HIDE_FROM_ABI constexpr array, _Size> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array, _Size> to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { static_assert(!is_array_v<_Tp>, "[array.creation]/1: to_array does not accept multidimensional arrays."); static_assert(is_constructible_v<_Tp, _Tp&>, "[array.creation]/1: to_array requires copy constructible elements."); @@ -547,7 +580,7 @@ to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { } template -_LIBCPP_HIDE_FROM_ABI constexpr array, _Size> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr array, _Size> to_array(_Tp (&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) { static_assert(!is_array_v<_Tp>, "[array.creation]/4: to_array does not accept multidimensional arrays."); static_assert(is_move_constructible_v<_Tp>, "[array.creation]/4: to_array requires move constructible elements."); diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp index 25a2f80b48f02..15bfdcc4f9e8c 100644 --- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp @@ -11,13 +11,96 @@ // check that functions are marked [[nodiscard]] #include +#include + +#include void array_test() { - std::array array; - array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::array a; + const std::array ca{9482}; + + a.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::get<0>(a); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(ca); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(std::move(a)); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(std::move(ca)); + +#if TEST_STD_VER >= 20 + std::to_array("zmt"); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_array({94, 82}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif } void empty_array_test() { - std::array array; - array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::array a; + const std::array ca; + + a.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + a.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp index e3efef988f0f4..b0e4b63d9a857 100644 --- a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp +++ b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp @@ -6,38 +6,42 @@ // //===----------------------------------------------------------------------===// -// // UNSUPPORTED: c++03, c++11, c++14, c++17 +// + +// template +// constexpr array, N> to_array(T (&a)[N]); +// template +// constexpr array, N> to_array(T (&&a)[N]); + #include -#include "test_macros.h" #include "MoveOnly.h" +#include "test_macros.h" // expected-warning@array:* 0-1 {{suggest braces around initialization of subobject}} -int main(int, char**) { +void test() { { char source[3][6] = {"hi", "world"}; // expected-error@array:* {{to_array does not accept multidimensional arrays}} // expected-error@array:* {{to_array requires copy constructible elements}} // expected-error@array:* 3 {{cannot initialize}} - std::to_array(source); // expected-note {{requested here}} + (void)std::to_array(source); // expected-note {{requested here}} } { MoveOnly mo[] = {MoveOnly{3}}; // expected-error@array:* {{to_array requires copy constructible elements}} // expected-error-re@array:* 1-2{{{{(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}} - std::to_array(mo); // expected-note {{requested here}} + (void)std::to_array(mo); // expected-note {{requested here}} } { const MoveOnly cmo[] = {MoveOnly{3}}; // expected-error@array:* {{to_array requires move constructible elements}} // expected-error-re@array:* 0-1{{{{(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}} - std::to_array(std::move(cmo)); // expected-note {{requested here}} + (void)std::to_array(std::move(cmo)); // expected-note {{requested here}} } - - return 0; } From d47bfcd50a1958f20ba9556347726a7db3cf53e4 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Thu, 20 Nov 2025 18:57:24 +0200 Subject: [PATCH 2/7] Review comments --- libcxx/include/array | 7 ++++--- .../array/array.creation/to_array.verify.cpp | 14 +++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/libcxx/include/array b/libcxx/include/array index d346b50cfcd7a..0b0c85458999c 100644 --- a/libcxx/include/array +++ b/libcxx/include/array @@ -473,8 +473,8 @@ array(_Tp, _Args...) -> array<_Tp, 1 + sizeof...(_Args)>; # endif template -inline _LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return std::equal(__x.begin(), __x.end(), __y.begin()); } @@ -545,7 +545,8 @@ get(const array<_Tp, _Size>& __a) _NOEXCEPT { } template -[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& +get(array<_Tp, _Size>&& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); return std::move(__a.__elems_[_Ip]); } diff --git a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp index b0e4b63d9a857..ee8d8e6cfb2e5 100644 --- a/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp +++ b/libcxx/test/std/containers/sequences/array/array.creation/to_array.verify.cpp @@ -6,23 +6,17 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 - // - -// template -// constexpr array, N> to_array(T (&a)[N]); -// template -// constexpr array, N> to_array(T (&&a)[N]); +// UNSUPPORTED: c++03, c++11, c++14, c++17 #include -#include "MoveOnly.h" #include "test_macros.h" +#include "MoveOnly.h" // expected-warning@array:* 0-1 {{suggest braces around initialization of subobject}} -void test() { +int main(int, char**) { { char source[3][6] = {"hi", "world"}; // expected-error@array:* {{to_array does not accept multidimensional arrays}} @@ -44,4 +38,6 @@ void test() { // expected-error-re@array:* 0-1{{{{(call to implicitly-deleted copy constructor of 'MoveOnly')|(call to deleted constructor of 'MoveOnly')}}}} (void)std::to_array(std::move(cmo)); // expected-note {{requested here}} } + + return 0; } From e4ec4d1a11d9fa80258314de14e80831bf6ee74a Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 21 Nov 2025 06:59:51 +0200 Subject: [PATCH 3/7] Addressed review comments --- .../diagnostics/array.nodiscard.verify.cpp | 148 ++++++++---------- 1 file changed, 64 insertions(+), 84 deletions(-) diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp index 15bfdcc4f9e8c..dff0cd1c26336 100644 --- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp @@ -15,92 +15,72 @@ #include -void array_test() { - std::array a; - const std::array ca{9482}; - - a.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - std::get<0>(a); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::get<0>(ca); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::get<0>(std::move(a)); - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::get<0>(std::move(ca)); +template +void test_members() { + std::array a; + const std::array ca{}; + + a.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.max_size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.empty(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + + a.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} +} +void test_nonmembers() { + { + std::array a; + const std::array ca{}; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(a); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(ca); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(std::move(a)); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(std::move(ca)); + } + + { #if TEST_STD_VER >= 20 - std::to_array("zmt"); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::to_array({94, 82}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_array("zmt"); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_array({94, 82, 49}); #endif + } } -void empty_array_test() { - std::array a; - const std::array ca; - - a.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.crbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.crend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.max_size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - a.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - - a.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} +void test() { + test_members<0>(); + test_members<82>(); +} \ No newline at end of file From 5c44d0835558b6867dde9237b06bbe647fb7e7d5 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 21 Nov 2025 07:07:23 +0200 Subject: [PATCH 4/7] Formatting --- libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp index dff0cd1c26336..1ee5fe5f77884 100644 --- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp @@ -83,4 +83,4 @@ void test_nonmembers() { void test() { test_members<0>(); test_members<82>(); -} \ No newline at end of file +} From 21b948f21f2d96b99c1bf6a766e64daf2389bf06 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 21 Nov 2025 09:34:06 +0200 Subject: [PATCH 5/7] Shorten test --- .../diagnostics/array.nodiscard.verify.cpp | 93 ++++++++----------- 1 file changed, 39 insertions(+), 54 deletions(-) diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp index 1ee5fe5f77884..4c99c3cc0f6b3 100644 --- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp @@ -15,72 +15,57 @@ #include -template +template void test_members() { - std::array a; - const std::array ca{}; + ArrT a{}; - a.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.begin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.end(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rbegin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rend(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cbegin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cend(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crbegin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crend(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.max_size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.empty(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.size(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.max_size(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.empty(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a[0]; // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.at(0); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.front(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.back(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - ca.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.data(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} } -void test_nonmembers() { - { - std::array a; - const std::array ca{}; +template +void test_get() { + ArrT a{}; - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::get<0>(a); - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::get<0>(ca); - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::get<0>(std::move(a)); - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::get<0>(std::move(ca)); - } + // expected-warning@+1 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(a); + // expected-warning@+1 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::get<0>(std::move(a)); +} - { #if TEST_STD_VER >= 20 - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::to_array("zmt"); - // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} - std::to_array({94, 82, 49}); -#endif - } +void test_to_array() { + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_array("zmt"); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_array({94, 82, 49}); } +#endif void test() { - test_members<0>(); - test_members<82>(); + test_members>(); + test_members>(); + test_members>(); + test_members>(); + + test_get>(); + test_get>(); } From 679fbf0b4fdaf9c8fe335e0950afd9cf18340b98 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 21 Nov 2025 18:18:03 +0200 Subject: [PATCH 6/7] Lengthen test --- .../diagnostics/array.nodiscard.verify.cpp | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp index 4c99c3cc0f6b3..a248bf88d8473 100644 --- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp @@ -15,39 +15,53 @@ #include -template +template void test_members() { - ArrT a{}; + std::array a; + const std::array ca{}; - a.begin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.end(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rbegin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.rend(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cbegin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.cend(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crbegin(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.crend(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.begin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.end(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.rend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.cend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crbegin(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.crend(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.size(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.max_size(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.empty(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.max_size(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.empty(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a[0]; // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.at(0); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca[0]; // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.at(0); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.front(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.back(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.front(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.back(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} - a.data(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}} + a.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + ca.data(); // expected-warning 2 {{ignoring return value of function declared with 'nodiscard' attribute}} } template void test_get() { - ArrT a{}; + std::array a{}; - // expected-warning@+1 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} std::get<0>(a); - // expected-warning@+1 2 {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} std::get<0>(std::move(a)); } @@ -61,11 +75,6 @@ void test_to_array() { #endif void test() { - test_members>(); - test_members>(); - test_members>(); - test_members>(); - - test_get>(); - test_get>(); + test_members<0>(); + test_members<82>(); } From d8790a10f6d4606f28a1bfb5f4bcdefaa55b7d4d Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 21 Nov 2025 18:19:00 +0200 Subject: [PATCH 7/7] Fix --- libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp index a248bf88d8473..8e49807732de7 100644 --- a/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp @@ -57,7 +57,7 @@ void test_members() { template void test_get() { - std::array a{}; + std::array a{}; // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} std::get<0>(a);