[libcxx-commits] [libcxx] [libc++] Apply `[[nodiscard]]` to `wstring_convert`, `wbuffer_convert` (PR #205486)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jun 23 22:49:14 PDT 2026
https://github.com/frederick-vs-ja created https://github.com/llvm/llvm-project/pull/205486
`[[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
>From 886ced378efa7c7e2567feac6e65c6ae83f25df2 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 24 Jun 2026 13:43:53 +0800
Subject: [PATCH] [libc++] Apply `[[nodiscard]]` to `wstring_convert`,
`wbuffer_convert`
`[[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
---
libcxx/include/__locale_dir/wbuffer_convert.h | 4 +-
libcxx/include/__locale_dir/wstring_convert.h | 22 +++++-----
.../libcxx/localization/nodiscard.verify.cpp | 41 +++++++++++++++++++
3 files changed, 55 insertions(+), 12 deletions(-)
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}}
+ }
}
More information about the libcxx-commits
mailing list