From 334f14457ae04cd8f1f9139c0e5f70ed56b0ad70 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 14 Nov 2025 11:22:09 +0200 Subject: [PATCH 1/8] [libc++][span] Mark functions as `[[nodiscard]]` --- libcxx/include/span | 90 +++++++++++-------- .../views/views.span/nodiscard.verify.cpp | 80 +++++++++++++++++ 2 files changed, 133 insertions(+), 37 deletions(-) create mode 100644 libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp diff --git a/libcxx/include/span b/libcxx/include/span index 3d4f9e4ba7831..1911badd88cb1 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -310,30 +310,32 @@ public: } template - _LIBCPP_HIDE_FROM_ABI constexpr span first() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span first() const noexcept { static_assert(_Count <= _Extent, "span::first(): Count out of range"); return span{data(), _Count}; } template - _LIBCPP_HIDE_FROM_ABI constexpr span last() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span last() const noexcept { static_assert(_Count <= _Extent, "span::last(): Count out of range"); return span{data() + size() - _Count, _Count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span first(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span + first(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span::first(count): count out of range"); return {data(), __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span last(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span + last(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span::last(count): count out of range"); return {data() + size() - __count, __count}; } template - _LIBCPP_HIDE_FROM_ABI constexpr auto - subspan() const noexcept -> span { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept + -> span { static_assert(_Offset <= _Extent, "span::subspan(): Offset out of range"); static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "span::subspan(): Offset + Count out of range"); @@ -342,7 +344,7 @@ public: return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span::subspan(offset, count): offset out of range"); if (__count == dynamic_extent) @@ -352,52 +354,58 @@ public: return {data() + __offset, __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { + return _Extent * sizeof(element_type); + } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; } - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span::operator[](index): index out of range"); return __data_[__idx]; } # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { if (__index >= size()) std::__throw_out_of_range("span"); return __data_[__index]; } # endif - _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span::front() on empty span"); return __data_[0]; } - _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span::back() on empty span"); return __data_[size() - 1]; } - _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } // [span.iter], span iterator support - _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data(), data(), data() + size()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else return iterator(data() + size()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { + return reverse_iterator(end()); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { + return reverse_iterator(begin()); + } _LIBCPP_HIDE_FROM_ABI span __as_bytes() const noexcept { return span{reinterpret_cast(data()), size_bytes()}; @@ -478,36 +486,38 @@ public: : __data_{__other.data()}, __size_{__other.size()} {} template - _LIBCPP_HIDE_FROM_ABI constexpr span first() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span first() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span::first(): Count out of range"); return span{data(), _Count}; } template - _LIBCPP_HIDE_FROM_ABI constexpr span last() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span last() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span::last(): Count out of range"); return span{data() + size() - _Count, _Count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span first(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span + first(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span::first(count): count out of range"); return {data(), __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr span last(size_type __count) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span + last(size_type __count) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span::last(count): count out of range"); return {data() + size() - __count, __count}; } template - _LIBCPP_HIDE_FROM_ABI constexpr span subspan() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span subspan() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span::subspan(): Offset out of range"); _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, "span::subspan(): Offset + Count out of range"); return span{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } - constexpr span _LIBCPP_HIDE_FROM_ABI + [[nodiscard]] constexpr span _LIBCPP_HIDE_FROM_ABI subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span::subspan(offset, count): offset out of range"); if (__count == dynamic_extent) @@ -517,52 +527,58 @@ public: return {data() + __offset, __count}; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } - _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { + return __size_ * sizeof(element_type); + } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; } - _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span::operator[](index): index out of range"); return __data_[__idx]; } # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { if (__index >= size()) std::__throw_out_of_range("span"); return __data_[__index]; } # endif - _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span::front() on empty span"); return __data_[0]; } - _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span::back() on empty span"); return __data_[size() - 1]; } - _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } // [span.iter], span iterator support - _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data(), data(), data() + size()); # else return iterator(data()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { # ifdef _LIBCPP_ABI_BOUNDED_ITERATORS return std::__make_bounded_iter(data() + size(), data(), data() + size()); # else return iterator(data() + size()); # endif } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { + return reverse_iterator(end()); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { + return reverse_iterator(begin()); + } _LIBCPP_HIDE_FROM_ABI span __as_bytes() const noexcept { return {reinterpret_cast(data()), size_bytes()}; @@ -585,13 +601,13 @@ inline constexpr bool ranges::enable_view> = true; // as_bytes & as_writable_bytes template -_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { return __s.__as_bytes(); } template requires(!is_const_v<_Tp>) -_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { return __s.__as_writable_bytes(); } diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp new file mode 100644 index 0000000000000..96c09e3540bd1 --- /dev/null +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: std-at-least-c++20 + +// + +// Check that functions are marked [[nodiscard]] + +#include +#include +#include + +#include "test_macros.h" + +void test() { + { // Test with a static extent + std::array arr{94, 92}; + std::span sp{arr}; + + sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan<0, 1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan(0, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#if TEST_STD_VER >= 26 + sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + sp.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::as_bytes(sp); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_writable_bytes(sp); + } + { // Test with a dynamic extent + std::vector vec{94, 92}; + std::span sp{vec}; + + sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan<0, 1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan(0, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#if TEST_STD_VER >= 26 + sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +#endif + sp.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.back(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.data(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.rend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::as_bytes(sp); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + std::as_writable_bytes(sp); + } +} From 91349620d58b9fd69b2c8d24734986f045e14686 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 14 Nov 2025 13:26:07 +0200 Subject: [PATCH 2/8] Update libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp Co-authored-by: Nikolas Klauser --- .../libcxx/containers/views/views.span/nodiscard.verify.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp index 96c09e3540bd1..251ac784c2450 100644 --- a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -20,8 +20,7 @@ void test() { { // Test with a static extent - std::array arr{94, 92}; - std::span sp{arr}; + std::span sp; sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From 34ea8ee6f73b7cc86602316e2e3343e59c93b823 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 14 Nov 2025 13:26:17 +0200 Subject: [PATCH 3/8] Update libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp Co-authored-by: Nikolas Klauser --- .../libcxx/containers/views/views.span/nodiscard.verify.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp index 251ac784c2450..60bad7f14ecba 100644 --- a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -48,8 +48,7 @@ void test() { std::as_writable_bytes(sp); } { // Test with a dynamic extent - std::vector vec{94, 92}; - std::span sp{vec}; + std::span sp; sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From fb96a81f2de04e4a2bdd051e79cf68c6b30a9e8d Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 14 Nov 2025 13:27:24 +0200 Subject: [PATCH 4/8] Apply suggestion from @Zingam --- .../test/libcxx/containers/views/views.span/nodiscard.verify.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp index 60bad7f14ecba..5ab051e51fc2a 100644 --- a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -12,7 +12,6 @@ // Check that functions are marked [[nodiscard]] -#include #include #include From 1fee6e0f8879ba51df068d48a46235bb72c0b6e2 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 14 Nov 2025 13:28:06 +0200 Subject: [PATCH 5/8] Apply suggestion from @Zingam --- .../test/libcxx/containers/views/views.span/nodiscard.verify.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp index 5ab051e51fc2a..f70a5f48ed63f 100644 --- a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -13,7 +13,6 @@ // Check that functions are marked [[nodiscard]] #include -#include #include "test_macros.h" From de00bf4f37663417e23370ea3ead4c1f7c939545 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 14 Nov 2025 19:09:08 +0200 Subject: [PATCH 6/8] Fix the fix --- .../containers/views/views.span/nodiscard.verify.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp index f70a5f48ed63f..87d04e0c9478e 100644 --- a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -12,13 +12,16 @@ // Check that functions are marked [[nodiscard]] +#include #include +#include #include "test_macros.h" void test() { { // Test with a static extent - std::span sp; + std::array arr{94, 82}; + std::span sp{arr}; sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} @@ -46,7 +49,8 @@ void test() { std::as_writable_bytes(sp); } { // Test with a dynamic extent - std::span sp; + std::vector vec{94, 82}; + std::span sp{vec}; sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From 0b01b4258933bfb1427fa4cd5185b9d61d26b1ff Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Fri, 14 Nov 2025 19:24:53 +0200 Subject: [PATCH 7/8] Cleanup --- .../libcxx/containers/views/views.span/nodiscard.verify.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp index 87d04e0c9478e..08739a583cf55 100644 --- a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -14,13 +14,12 @@ #include #include -#include #include "test_macros.h" void test() { { // Test with a static extent - std::array arr{94, 82}; + std::array arr{94, 82}; std::span sp{arr}; sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} @@ -49,8 +48,7 @@ void test() { std::as_writable_bytes(sp); } { // Test with a dynamic extent - std::vector vec{94, 82}; - std::span sp{vec}; + std::span sp; sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From 423da0bbae67706f0c01934f9becab8ff14c71c1 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Mon, 17 Nov 2025 13:29:55 +0200 Subject: [PATCH 8/8] Addressed comments --- .../views/views.span/nodiscard.verify.cpp | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp index 08739a583cf55..666680597f147 100644 --- a/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -12,22 +12,20 @@ // Check that functions are marked [[nodiscard]] -#include #include #include "test_macros.h" void test() { { // Test with a static extent - std::array arr{94, 82}; - std::span sp{arr}; + std::span sp; - sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.first(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.last(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.subspan<0, 1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.subspan(0, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan<0, 0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} @@ -50,12 +48,12 @@ void test() { { // Test with a dynamic extent std::span sp; - sp.first<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.last<1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.first(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.last(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.subspan<0, 1>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sp.subspan(0, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last<0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.first(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.last(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan<0, 0>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sp.subspan(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.size_bytes(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sp.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}