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::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 #include #include #include @@ -242,4 +245,42 @@ void test() { f.get(0, 0, 0, std::wstring()); } #endif + + // C++23 [depr.conversions.string] + { + typedef std::wstring_convert, char16_t> converter_type; + + converter_type myconv; + converter_type::byte_string bs; + converter_type::wide_string ws; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + myconv.from_bytes('*'); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + myconv.from_bytes(""); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + myconv.from_bytes(bs); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + myconv.from_bytes(bs.data(), bs.data()); + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + myconv.to_bytes(char16_t()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + myconv.to_bytes(ws.data()); + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + myconv.to_bytes(ws); + // expected-warning@+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, 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}} + } }