[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 23:11:55 PDT 2026
https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/205486
>From 29a49d2b0a5431e97e5780d04e89ccb9c14ff095 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 +++++-----
.../conversions.string/ctor_move.pass.cpp | 2 +-
.../libcxx/localization/nodiscard.verify.cpp | 41 +++++++++++++++++++
4 files changed, 56 insertions(+), 13 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/extensions/libcxx/localization/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp b/libcxx/test/extensions/libcxx/localization/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp
index a536e6e9b04c6..6cf0c68232cd0 100644
--- a/libcxx/test/extensions/libcxx/localization/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp
+++ b/libcxx/test/extensions/libcxx/localization/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp
@@ -31,7 +31,7 @@ int main(int, char**)
// create a converter and perform some conversions to generate some
// interesting state.
Myconv myconv;
- myconv.from_bytes("\xEF\xBF\xBD");
+ (void)myconv.from_bytes("\xEF\xBF\xBD");
const auto old_converted = myconv.converted();
assert(myconv.converted() == 3);
// move construct a new converter and make sure the state is the same.
diff --git a/libcxx/test/libcxx/localization/nodiscard.verify.cpp b/libcxx/test/libcxx/localization/nodiscard.verify.cpp
index 80691e276deab..dd14091b90182 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(char16_t());
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ myconv.to_bytes(ws.data());
+ // 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