diff --git a/libcxx/include/string b/libcxx/include/string index 6b42cb2c7586d..2b3ba6d2d9b62 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -3851,46 +3851,52 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Tra __lhs.swap(__rhs); } -_LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long long stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); - -_LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); - -_LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); -_LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long +stoul(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long +stoll(const string& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long +stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const string& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const string& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); # if _LIBCPP_HAS_WIDE_CHARACTERS -_LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI long long stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); -_LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); - -_LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); -_LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); - -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); -_LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int stoi(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long stol(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long +stoul(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long long +stoll(const wstring& __str, size_t* __idx = nullptr, int __base = 10); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unsigned long long +stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI float stof(const wstring& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); + +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); +[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); # endif // _LIBCPP_HAS_WIDE_CHARACTERS template @@ -3899,7 +3905,7 @@ _LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocato template struct __string_hash : public __unary_function, _Allocator>, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); } @@ -3970,30 +3976,31 @@ erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) { // Literal suffixes for basic_string [basic.string.literals] inline namespace literals { inline namespace string_literals { -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator""s(const char* __str, size_t __len) { return basic_string(__str, __len); } # if _LIBCPP_HAS_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string -operator""s(const wchar_t* __str, size_t __len) { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator""s(const wchar_t* __str, size_t __len) { return basic_string(__str, __len); } # endif # if _LIBCPP_HAS_CHAR8_T -inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string operator""s(const char8_t* __str, size_t __len) { +[[__nodiscard__]] inline + _LIBCPP_HIDE_FROM_ABI constexpr basic_string operator""s(const char8_t* __str, size_t __len) { return basic_string(__str, __len); } # endif -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string -operator""s(const char16_t* __str, size_t __len) { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator""s(const char16_t* __str, size_t __len) { return basic_string(__str, __len); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string operator""s(const char32_t* __str, size_t __len) { return basic_string(__str, __len); } diff --git a/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp index f020516a2495a..0ff92cac3a3b2 100644 --- a/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp @@ -130,3 +130,80 @@ void test() { str.subview(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} #endif } + +void test_nonmembers() { + // Numeric conversions + + std::string str; + + std::stoi(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stol(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoll(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoull(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::stof(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stod(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stold(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::to_string(94); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82UL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94LL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82ULL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94.0F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(82.0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_string(94.0L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#if !defined(TEST_HAS_NO_WIDE_CHARACTERS) + + std::wstring wstr; + + std::stoi(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stol(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoll(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stoull(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::stof(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stod(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::stold(wstr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + std::to_wstring(94); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82UL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94LL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82ULL); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94.0F); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(82.0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::to_wstring(94.0L); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#endif + + // std::hash<> + + std::hash hash; + + hash(str); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + +#if TEST_STD_VER >= 14 + // string literals + + using namespace std::string_literals; + + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + ""s; // const char* +# if !defined(TEST_HAS_NO_WIDE_CHARACTERS) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + L""s; // const wchar_t* +# endif +# if !defined(TEST_HAS_NO_CHAR8_T) + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + u8""s; // const char8_t* +# endif + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + u""s; // const char16_t* + // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}} + U""s; // const char32_t* +#endif +}