[libcxx-commits] [libcxx] [libc++] Applied `[[nodiscard]]` to `<fstream>`, `<sstream>`, `<strstream>`, `<synchstream>` (PR #173842)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Dec 29 01:01:51 PST 2025
https://github.com/H-G-Hristov created https://github.com/llvm/llvm-project/pull/173842
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html
- https://wg21.link/input.output
Towards #172124
>From e41a8adc35fa52153de0b2690df86c232d10a9ac Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 29 Dec 2025 11:01:28 +0200
Subject: [PATCH] [libc++] Applied `[[nodiscard]]` to `<fstream>`, `<sstream>`,
`<strstream>`, `<synchstream>`
`[[nodiscard]]` should be applied to functions where discarding the return value is most likely a correctness issue.
- https://libcxx.llvm.org/CodingGuidelines.html
- https://wg21.link/input.output
Towards #172124
---
libcxx/include/fstream | 28 +++--
libcxx/include/sstream | 50 ++++-----
libcxx/include/strstream | 2 +-
libcxx/include/syncstream | 8 +-
.../fstreams/nodiscard.verify.cpp | 67 ++++++++++++
.../string.streams/nodiscard.verify.cpp | 101 ++++++++++++++++++
.../synchstream/nodiscard.verify.cpp | 35 ++++++
7 files changed, 251 insertions(+), 40 deletions(-)
create mode 100644 libcxx/test/libcxx/input.output/file.streams/fstreams/nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx/input.output/string.streams/nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx/input.output/synchstream/nodiscard.verify.cpp
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index 95fc8129fa206..a0ff33023f8d0 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -254,7 +254,7 @@ public:
void swap(basic_filebuf& __rhs);
// 27.9.1.4 Members:
- _LIBCPP_HIDE_FROM_ABI bool is_open() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
basic_filebuf* open(const char* __s, ios_base::openmode __mode);
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
@@ -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_);
@@ -1163,11 +1163,13 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
_LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
- _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* 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;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
void open(const char* __s, ios_base::openmode __mode = ios_base::in);
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
@@ -1319,11 +1321,13 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
_LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
- _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* 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;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
void open(const char* __s, ios_base::openmode __mode = ios_base::out);
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
@@ -1481,11 +1485,13 @@ public:
_LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
- _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* 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;
+ [[__nodiscard__]] _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);
# if _LIBCPP_HAS_OPEN_WITH_WCHAR
void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
diff --git a/libcxx/include/sstream b/libcxx/include/sstream
index c42dbff9eee5f..78962a6e5b42d 100644
--- a/libcxx/include/sstream
+++ b/libcxx/include/sstream
@@ -461,15 +461,15 @@ public:
// [stringbuf.members] Member functions:
# if _LIBCPP_STD_VER >= 20
- _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
# endif
# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
- string_type str() const;
+ [[__nodiscard__]] string_type str() const;
# else
- _LIBCPP_HIDE_FROM_ABI string_type str() const& { return str(__str_.get_allocator()); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return str(__str_.get_allocator()); }
- _LIBCPP_HIDE_FROM_ABI string_type str() && {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && {
const basic_string_view<_CharT, _Traits> __view = view();
typename string_type::size_type __pos = __view.empty() ? 0 : __view.data() - __str_.data();
// In C++23, this is just string_type(std::move(__str_), __pos, __view.size(), __str_.get_allocator());
@@ -485,11 +485,11 @@ public:
# if _LIBCPP_STD_VER >= 20
template <class _SAlloc>
requires __is_allocator_v<_SAlloc>
- _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
}
- _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
# endif // _LIBCPP_STD_VER >= 20
void str(const string_type& __s) {
@@ -949,26 +949,26 @@ public:
}
// [istringstream.members] Member functions:
- _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
}
# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
- _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
# else
- _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
- _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
# endif
# if _LIBCPP_STD_VER >= 20
template <class _SAlloc>
requires __is_allocator_v<_SAlloc>
- _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
return __sb_.str(__sa);
}
- _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
# endif // _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
@@ -1087,26 +1087,26 @@ public:
}
// [ostringstream.members] Member functions:
- _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
}
# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
- _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
# else
- _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
- _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
# endif
# if _LIBCPP_STD_VER >= 20
template <class _SAlloc>
requires __is_allocator_v<_SAlloc>
- _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
return __sb_.str(__sa);
}
- _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
# endif // _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
@@ -1227,26 +1227,28 @@ public:
}
// [stringstream.members] Member functions:
- _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
}
# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
- _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
# else
- _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() const& { return __sb_.str(); }
- _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
# endif
# if _LIBCPP_STD_VER >= 20
template <class _SAlloc>
requires __is_allocator_v<_SAlloc>
- _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
return __sb_.str(__sa);
}
- _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept {
+ return __sb_.view();
+ }
# endif // _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
diff --git a/libcxx/include/strstream b/libcxx/include/strstream
index 1a17f8389c078..53b3067a136f7 100644
--- a/libcxx/include/strstream
+++ b/libcxx/include/strstream
@@ -297,7 +297,7 @@ public:
__sb_.swap(__rhs.__sb_);
}
- _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
_LIBCPP_HIDE_FROM_ABI void freeze(bool __freezefl = true) { __sb_.freeze(__freezefl); }
_LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
_LIBCPP_HIDE_FROM_ABI int pcount() const { return __sb_.pcount(); }
diff --git a/libcxx/include/syncstream b/libcxx/include/syncstream
index 1f7605e06aa21..bd64453683c7c 100644
--- a/libcxx/include/syncstream
+++ b/libcxx/include/syncstream
@@ -317,9 +317,9 @@ public:
_LIBCPP_HIDE_FROM_ABI bool emit() { return emit(false); }
- _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __wrapped_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __wrapped_; }
- _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
_LIBCPP_HIDE_FROM_ABI void set_emit_on_sync(bool __b) noexcept { __emit_on_sync_ = __b; }
@@ -496,9 +496,9 @@ public:
}
}
- _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __sb_.get_wrapped(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI streambuf_type* get_wrapped() const noexcept { return __sb_.get_wrapped(); }
- _LIBCPP_HIDE_FROM_ABI syncbuf_type* rdbuf() const noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI syncbuf_type* rdbuf() const noexcept {
return const_cast<syncbuf_type*>(std::addressof(__sb_));
}
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..98b09405e84e7
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/nodiscard.verify.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <fstream>
+
+#include "test_macros.h"
+
+void test() {
+ {
+ std::basic_filebuf<char> fb;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fb.is_open();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ fb.native_handle();
+#endif
+ }
+
+ {
+ std::basic_ifstream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.rdbuf();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.native_handle();
+#endif
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.is_open();
+ }
+
+ {
+ std::basic_ofstream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.rdbuf();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.native_handle();
+#endif
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.is_open();
+ }
+
+ {
+ std::basic_fstream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.rdbuf();
+#if TEST_STD_VER >= 26
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.native_handle();
+#endif
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.is_open();
+ }
+}
diff --git a/libcxx/test/libcxx/input.output/string.streams/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/string.streams/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..56ceb63b26697
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/string.streams/nodiscard.verify.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <sstream>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <memory>
+#include <sstream>
+#include <utility>
+
+#include "test_macros.h"
+
+void test() {
+#if TEST_STD_VER >= 20
+ std::allocator<char> alloc;
+#endif
+
+ {
+ std::basic_stringbuf<char> sb;
+
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sb.get_allocator();
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sb.str();
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(sb).str();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sb.str({});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sb.view();
+#endif
+ }
+
+ {
+ std::basic_istringstream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.rdbuf();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.str();
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(stream).str();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.str({});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.view();
+#endif
+ }
+
+ {
+ std::basic_ostringstream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.rdbuf();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.str();
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(stream).str();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.str({});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.view();
+#endif
+ }
+
+ {
+ std::basic_stringstream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.rdbuf();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.str();
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(stream).str();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.str({});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.view();
+#endif
+ }
+}
diff --git a/libcxx/test/libcxx/input.output/synchstream/nodiscard.verify.cpp b/libcxx/test/libcxx/input.output/synchstream/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..0e00daade21d4
--- /dev/null
+++ b/libcxx/test/libcxx/input.output/synchstream/nodiscard.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <synchstream>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <synchstream>
+
+#include "test_macros.h"
+
+void test() {
+ {
+ std::basic_synchbuf<char> sb;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sb.get_wrapped();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ sb.get_allocator();
+ }
+
+ {
+ std::basic_osynchstream<char> stream;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.get_wrapped();
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ stream.rdbuf();
+ }
+}
More information about the libcxx-commits
mailing list