From ea08a3c757dadff14d847c9a8b7b2df54eb0f717 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Sat, 8 Nov 2025 07:55:22 +0200 Subject: [PATCH] [libc++] Added `[[nodiscard]]` to `fstream.native_handle`, `span.at` and `in/out_ptr` ...according to Coding Guidelines: `[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue. At the time of impelentation the ``nodiscard` policy has not been established yet. I did it as a batch as the changes are trivial and minimal. --- libcxx/include/__memory/inout_ptr.h | 2 +- libcxx/include/__memory/out_ptr.h | 2 +- libcxx/include/fstream | 14 +++++--- libcxx/include/span | 4 +-- .../views/views.span/nodiscard.verify.cpp | 30 ++++++++++++++++ .../fstreams/nodiscard.verify.cpp | 34 +++++++++++++++++++ .../smartptr/adapt/nodiscard.verify.cpp | 23 +++++++++++++ 7 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/input.output/file.streams/fstreams/nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/utilities/smartptr/adapt/nodiscard.verify.cpp diff --git a/libcxx/include/__memory/inout_ptr.h b/libcxx/include/__memory/inout_ptr.h index ef345fe469bca..0fa685afb2ee6 100644 --- a/libcxx/include/__memory/inout_ptr.h +++ b/libcxx/include/__memory/inout_ptr.h @@ -96,7 +96,7 @@ class inout_ptr_t { }; template -_LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) { using _Ptr = conditional_t, __pointer_of_t<_Smart>, _Pointer>; return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...); } diff --git a/libcxx/include/__memory/out_ptr.h b/libcxx/include/__memory/out_ptr.h index e498e3307b9d6..23a77f6a0f7e9 100644 --- a/libcxx/include/__memory/out_ptr.h +++ b/libcxx/include/__memory/out_ptr.h @@ -88,7 +88,7 @@ class out_ptr_t { }; template -_LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) { using _Ptr = conditional_t, __pointer_of_t<_Smart>, _Pointer>; return std::out_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...); } diff --git a/libcxx/include/fstream b/libcxx/include/fstream index 1f88d134fe061..2371e460ddf9e 100644 --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -269,7 +269,7 @@ public: _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode); basic_filebuf* close(); # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened"); # if defined(_LIBCPP_WIN32API) return std::__filebuf_windows_native_handle(__file_); @@ -1165,7 +1165,9 @@ public: _LIBCPP_HIDE_FROM_ABI basic_filebuf* rdbuf() const; # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { + return rdbuf()->native_handle(); + } # endif _LIBCPP_HIDE_FROM_ABI bool is_open() const; void open(const char* __s, ios_base::openmode __mode = ios_base::in); @@ -1321,7 +1323,9 @@ public: _LIBCPP_HIDE_FROM_ABI basic_filebuf* rdbuf() const; # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { + return rdbuf()->native_handle(); + } # endif _LIBCPP_HIDE_FROM_ABI bool is_open() const; void open(const char* __s, ios_base::openmode __mode = ios_base::out); @@ -1483,7 +1487,9 @@ public: _LIBCPP_HIDE_FROM_ABI basic_filebuf* rdbuf() const; # if _LIBCPP_STD_VER >= 26 - _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { + return rdbuf()->native_handle(); + } # endif _LIBCPP_HIDE_FROM_ABI bool is_open() const; _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); diff --git a/libcxx/include/span b/libcxx/include/span index 3d4f9e4ba7831..68fa3d5987310 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -362,7 +362,7 @@ public: } # 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]; @@ -527,7 +527,7 @@ public: } # 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]; 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..6deec90aa0f00 --- /dev/null +++ b/libcxx/test/libcxx/containers/views/views.span/nodiscard.verify.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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++26 + +// + +// Check that functions are marked [[nodiscard]] + +#include +#include +#include + +void test() { + { // Test with static extent + std::array arr{94, 92}; + std::span sp{arr}; + sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { // Test with dynamic extent + std::vector vec{94, 92}; + std::span sp{vec}; + sp.at(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +} diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/nodiscard.verify.cpp new file mode 100644 index 0000000000000..4aeef4141693c --- /dev/null +++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/nodiscard.verify.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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++26 + +// + +// Check that functions are marked [[nodiscard]] + +#include + +void test() { + { + std::filebuf fb; + fb.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::fstream fs; + fs.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::ifstream fs; + fs.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } + { + std::ofstream fs; + fs.native_handle(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +} diff --git a/libcxx/test/libcxx/utilities/smartptr/adapt/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/smartptr/adapt/nodiscard.verify.cpp new file mode 100644 index 0000000000000..c026594f58d71 --- /dev/null +++ b/libcxx/test/libcxx/utilities/smartptr/adapt/nodiscard.verify.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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++23 + +// + +// Check that functions are marked [[nodiscard]] + +#include + +void test() { + std::unique_ptr uPtr; + // [inout.ptr] + std::inout_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + // [out.ptr] + std::out_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +}