[libcxx-commits] [libcxx] [libc++] Applied `[[nodiscard]]` to `<fstream>`, `<sstream>`, `<strstream>`, `<synchstream>` (PR #173842)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Dec 29 09:59:41 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Hristo Hristov (H-G-Hristov)

<details>
<summary>Changes</summary>

`[[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

---

Patch is 24.30 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/173842.diff


8 Files Affected:

- (modified) libcxx/include/fstream (+17-11) 
- (modified) libcxx/include/sstream (+30-24) 
- (modified) libcxx/include/strstream (+10-10) 
- (modified) libcxx/include/syncstream (+4-4) 
- (added) libcxx/test/libcxx/depr/depr.strstream/nodiscard.verify.cpp (+58) 
- (added) libcxx/test/libcxx/input.output/file.streams/fstreams/nodiscard.verify.cpp (+67) 
- (added) libcxx/test/libcxx/input.output/string.streams/nodiscard.verify.cpp (+101) 
- (added) libcxx/test/libcxx/input.output/synchstream/nodiscard.verify.cpp (+41) 


``````````diff
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index 95fc8129fa206..3f81d4217019b 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..a42e8fbc9b72e 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,28 @@ 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 +1089,28 @@ 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 +1231,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..b33977ff66e21 100644
--- a/libcxx/include/strstream
+++ b/libcxx/include/strstream
@@ -179,8 +179,8 @@ public:
   void swap(strstreambuf& __rhs);
 
   void freeze(bool __freezefl = true);
-  char* str();
-  int pcount() const;
+  [[__nodiscard__]] char* str();
+  [[__nodiscard__]] int pcount() const;
 
 protected:
   int_type overflow(int_type __c = EOF) override;
@@ -264,8 +264,8 @@ public:
     __sb_.swap(__rhs.__sb_);
   }
 
-  _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
-  _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI strstreambuf* rdbuf() const { return const_cast<strstreambuf*>(&__sb_); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
 
 private:
   strstreambuf __sb_;
@@ -297,10 +297,10 @@ 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(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int pcount() const { return __sb_.pcount(); }
 
 private:
   strstreambuf __sb_; // exposition only
@@ -340,10 +340,10 @@ public:
   }
 
   // Members:
-  _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 int pcount() const { return __sb_.pcount(); }
-  _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int pcount() const { return __sb_.pcount(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char* str() { return __sb_.str(); }
 
 private:
   strstreambuf __sb_; // exposition only
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/depr/depr.strstream/nodiscard.verify.cpp b/libcxx/test/libcxx/depr/depr.strstream/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..86db867ad9e41
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.strstream/nodiscard.verify.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_STRSTREAM
+
+// <strstream>
+
+// Check that functions are marked [[nodiscard]]
+
+#include <strstream>
+
+void test() {
+  {
+    std::strstreambuf sb;
+
+    // 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.pcount();
+  }
+
+  {
+    const char buff[] = "";
+    std::istrstream stream(buff);
+
+    // 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();
+  }
+
+  {
+    std::ostrstream 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();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    stream.pcount();
+  }
+
+  {
+    std::strstream 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();
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    stream.pcount();
+  }
+}
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..53422cb6f6888
--- /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 {{ig...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/173842


More information about the libcxx-commits mailing list