[libcxx-commits] [libcxx] [libc++] Apply `[[nodiscard]]` to `wstring_convert`, `wbuffer_convert` (PR #205486)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jun 23 22:49:42 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

<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://timsong-cpp.github.io/cppwp/n4950/depr.conversions.string
- https://timsong-cpp.github.io/cppwp/n4950/depr.conversions.buffer

---
Full diff: https://github.com/llvm/llvm-project/pull/205486.diff


3 Files Affected:

- (modified) libcxx/include/__locale_dir/wbuffer_convert.h (+2-2) 
- (modified) libcxx/include/__locale_dir/wstring_convert.h (+12-10) 
- (modified) libcxx/test/libcxx/localization/nodiscard.verify.cpp (+41) 


``````````diff
diff --git a/libcxx/include/__locale_dir/wbuffer_convert.h b/libcxx/include/__locale_dir/wbuffer_convert.h
index a6818aadf5d0b..c8bad68011a09 100644
--- a/libcxx/include/__locale_dir/wbuffer_convert.h
+++ b/libcxx/include/__locale_dir/wbuffer_convert.h
@@ -67,7 +67,7 @@ class _LIBCPP_DEPRECATED_IN_CXX17 wbuffer_convert : public basic_streambuf<_Elem
 
   _LIBCPP_HIDE_FROM_ABI ~wbuffer_convert();
 
-  _LIBCPP_HIDE_FROM_ABI streambuf* rdbuf() const { return __bufptr_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI streambuf* rdbuf() const { return __bufptr_; }
   _LIBCPP_HIDE_FROM_ABI streambuf* rdbuf(streambuf* __bytebuf) {
     streambuf* __r = __bufptr_;
     __bufptr_      = __bytebuf;
@@ -77,7 +77,7 @@ class _LIBCPP_DEPRECATED_IN_CXX17 wbuffer_convert : public basic_streambuf<_Elem
   wbuffer_convert(const wbuffer_convert&)            = delete;
   wbuffer_convert& operator=(const wbuffer_convert&) = delete;
 
-  _LIBCPP_HIDE_FROM_ABI state_type state() const { return __st_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI state_type state() const { return __st_; }
 
 protected:
   _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type underflow();
diff --git a/libcxx/include/__locale_dir/wstring_convert.h b/libcxx/include/__locale_dir/wstring_convert.h
index 8f6dc9af8da91..05b81e0a880ed 100644
--- a/libcxx/include/__locale_dir/wstring_convert.h
+++ b/libcxx/include/__locale_dir/wstring_convert.h
@@ -64,28 +64,30 @@ class _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert {
   wstring_convert(const wstring_convert& __wc)            = delete;
   wstring_convert& operator=(const wstring_convert& __wc) = delete;
 
-  _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(char __byte) { return from_bytes(&__byte, &__byte + 1); }
-  _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __ptr) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(char __byte) {
+    return from_bytes(&__byte, &__byte + 1);
+  }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __ptr) {
     return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));
   }
-  _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const byte_string& __str) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const byte_string& __str) {
     return from_bytes(__str.data(), __str.data() + __str.size());
   }
-  _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last);
 
-  _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(_Elem __wchar) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(_Elem __wchar) {
     return to_bytes(std::addressof(__wchar), std::addressof(__wchar) + 1);
   }
-  _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __wptr) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __wptr) {
     return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));
   }
-  _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const wide_string& __wstr) {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const wide_string& __wstr) {
     return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());
   }
-  _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last);
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last);
 
-  _LIBCPP_HIDE_FROM_ABI size_t converted() const _NOEXCEPT { return __cvtcount_; }
-  _LIBCPP_HIDE_FROM_ABI state_type state() const { return __cvtstate_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t converted() const _NOEXCEPT { return __cvtcount_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI state_type state() const { return __cvtstate_; }
 };
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
diff --git a/libcxx/test/libcxx/localization/nodiscard.verify.cpp b/libcxx/test/libcxx/localization/nodiscard.verify.cpp
index 80691e276deab..5f934f574757c 100644
--- a/libcxx/test/libcxx/localization/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/localization/nodiscard.verify.cpp
@@ -7,9 +7,12 @@
 //===----------------------------------------------------------------------===//
 
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT
 
 // Check that functions are marked [[nodiscard]]
 
+#include <codecvt>
 #include <cwchar>
 #include <locale>
 #include <string>
@@ -242,4 +245,42 @@ void test() {
     f.get(0, 0, 0, std::wstring());
   }
 #endif
+
+  // C++23 [depr.conversions.string]
+  {
+    typedef std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter_type;
+
+    converter_type myconv;
+    converter_type::byte_string bs;
+    converter_type::wide_string ws;
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.from_bytes('*');
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.from_bytes("");
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.from_bytes(bs);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.from_bytes(bs.data(), bs.data());
+
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.to_bytes(u'*');
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.to_bytes(u"");
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.to_bytes(ws);
+    // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.to_bytes(ws.data(), ws.data());
+
+    myconv.converted(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.state();     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  }
+
+  // C++23 [depr.conversions.buffer]
+  {
+    std::wbuffer_convert<std::codecvt_utf8<char16_t>, char16_t> myconv;
+
+    myconv.rdbuf(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    myconv.state(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  }
 }

``````````

</details>


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


More information about the libcxx-commits mailing list