diff options
Diffstat (limited to 'libcxx')
10 files changed, 70 insertions, 109 deletions
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst index 04f1661..2b62a36 100644 --- a/libcxx/docs/ReleaseNotes/19.rst +++ b/libcxx/docs/ReleaseNotes/19.rst @@ -65,7 +65,7 @@ Deprecations and Removals provided, and such a base template is bound to be incorrect for some types, which could currently cause unexpected behavior while going undetected. -- TODO: The ``_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT`` macro that changed the behavior for narrowing conversions +- The ``_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT`` macro that changed the behavior for narrowing conversions in ``std::variant`` has been removed in LLVM 19. - TODO: The ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`` macro has been removed in LLVM 19. diff --git a/libcxx/include/variant b/libcxx/include/variant index d1eea52..59d7f9b 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -347,13 +347,13 @@ inline constexpr size_t variant_npos = static_cast<size_t>(-1); template <size_t _NumAlternatives> _LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() { -#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +# ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION if constexpr (_NumAlternatives < numeric_limits<unsigned char>::max()) return static_cast<unsigned char>(0); else if constexpr (_NumAlternatives < numeric_limits<unsigned short>::max()) return static_cast<unsigned short>(0); else -#endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +# endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION return static_cast<unsigned int>(0); } @@ -1085,13 +1085,9 @@ struct __narrowing_check { }; template <class _Dest, class _Source> -using __check_for_narrowing _LIBCPP_NODEBUG = typename _If< -# ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT - false && -# endif - is_arithmetic<_Dest>::value, - __narrowing_check, - __no_narrowing_check >::template _Apply<_Dest, _Source>; +using __check_for_narrowing _LIBCPP_NODEBUG = + typename _If< is_arithmetic<_Dest>::value, __narrowing_check, __no_narrowing_check >::template _Apply<_Dest, + _Source>; template <class _Tp, size_t _Idx> struct __overload { @@ -1099,24 +1095,6 @@ struct __overload { auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>; }; -// TODO(LLVM-19): Remove all occurrences of this macro. -# ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT -template <class _Tp, size_t> -struct __overload_bool { - template <class _Up, class _Ap = __remove_cvref_t<_Up>> - auto operator()(bool, _Up&&) const -> enable_if_t<is_same_v<_Ap, bool>, __type_identity<_Tp>>; -}; - -template <size_t _Idx> -struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {}; -template <size_t _Idx> -struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {}; -template <size_t _Idx> -struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {}; -template <size_t _Idx> -struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {}; -# endif - template <class... _Bases> struct __all_overloads : _Bases... { void operator()() const; diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp index 068202c..d4bbde7 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/generic_category.pass.cpp @@ -44,14 +44,19 @@ int main(int, char**) errno = E2BIG; // something that message will never generate const std::error_category& e_cat1 = std::generic_category(); const std::string msg = e_cat1.message(-1); - // Exact message format varies by platform. -#if defined(_AIX) - LIBCPP_ASSERT(msg.rfind("Error -1 occurred", 0) == 0); -#elif defined(_NEWLIB_VERSION) - LIBCPP_ASSERT(msg.empty()); -#else - LIBCPP_ASSERT(msg.rfind("Unknown error", 0) == 0); + // Exact message format varies by platform. We can't detect + // some of these (Musl in particular) using the preprocessor, + // so accept a few sensible messages. Newlib unfortunately + // responds with an empty message, which we probably want to + // treat as a failure code otherwise, but we can detect that + // with the preprocessor. + LIBCPP_ASSERT(msg.rfind("Error -1 occurred", 0) == 0 // AIX + || msg.rfind("No error information", 0) == 0 // Musl + || msg.rfind("Unknown error", 0) == 0 // Glibc +#if defined(_NEWLIB_VERSION) + || msg.empty() #endif + ); assert(errno == E2BIG); } diff --git a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp index 42fdd1c..eefbddd 100644 --- a/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp +++ b/libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp @@ -50,14 +50,19 @@ int main(int, char**) { errno = E2BIG; // something that message will never generate const std::error_category& e_cat1 = std::system_category(); const std::string msg = e_cat1.message(-1); - // Exact message format varies by platform. -#if defined(_AIX) - LIBCPP_ASSERT(msg.rfind("Error -1 occurred", 0) == 0); -#elif defined(_NEWLIB_VERSION) - LIBCPP_ASSERT(msg.empty()); -#else - LIBCPP_ASSERT(msg.rfind("Unknown error", 0) == 0); + // Exact message format varies by platform. We can't detect + // some of these (Musl in particular) using the preprocessor, + // so accept a few sensible messages. Newlib unfortunately + // responds with an empty message, which we probably want to + // treat as a failure code otherwise, but we can detect that + // with the preprocessor. + LIBCPP_ASSERT(msg.rfind("Error -1 occurred", 0) == 0 // AIX + || msg.rfind("No error information", 0) == 0 // Musl + || msg.rfind("Unknown error", 0) == 0 // Glibc +#if defined(_NEWLIB_VERSION) + || msg.empty() #endif + ); assert(errno == E2BIG); } diff --git a/libcxx/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp b/libcxx/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp index 8637a93..0258ebf 100644 --- a/libcxx/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp @@ -22,6 +22,7 @@ #include <locale> #include <ios> #include <cassert> +#include <cstdio> #include <streambuf> #include <cmath> #include "test_macros.h" @@ -8934,11 +8935,12 @@ void test4() char str[200]; std::locale lc = std::locale::classic(); std::locale lg(lc, new my_numpunct); -#ifdef _AIX - std::string inf = "INF"; -#else - std::string inf = "inf"; -#endif + + std::string inf; + + // This should match the underlying C library + std::sprintf(str, "%f", INFINITY); + inf = str; const my_facet f(1); { @@ -10727,24 +10729,27 @@ void test5() std::locale lc = std::locale::classic(); std::locale lg(lc, new my_numpunct); const my_facet f(1); -#if defined(_AIX) - std::string nan= "NaNQ"; - std::string NaN = "NaNQ"; - std::string nan_padding25 = "*********************"; - std::string pnan_sign = "+"; - std::string pnan_padding25 = "********************"; -#else - std::string nan= "nan"; - std::string NaN = "NAN"; - std::string nan_padding25 = "**********************"; -#if defined(TEST_HAS_GLIBC) || defined(_WIN32) - std::string pnan_sign = "+"; - std::string pnan_padding25 = "*********************"; -#else - std::string pnan_sign = ""; - std::string pnan_padding25 = "**********************"; -#endif -#endif + + std::string nan; + std::string NaN; + std::string pnan_sign; + + // The output here depends on the underlying C library, so work out what + // that does. + std::sprintf(str, "%f", std::nan("")); + nan = str; + + std::sprintf(str, "%F", std::nan("")); + NaN = str; + + std::sprintf(str, "%+f", std::nan("")); + if (str[0] == '+') { + pnan_sign = "+"; + } + + std::string nan_padding25 = std::string(25 - nan.length(), '*'); + std::string pnan_padding25 = std::string(25 - nan.length() - pnan_sign.length(), '*'); + { long double v = std::nan(""); std::ios ios(0); diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp index b3fc202..b38b10d 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp @@ -134,8 +134,7 @@ void test_T_assignment_sfinae() { } { using V = std::variant<std::string, float>; - static_assert(std::is_assignable<V, int>::value == VariantAllowsNarrowingConversions, - "no matching operator="); + static_assert(!std::is_assignable<V, int>::value, "no matching operator="); } { using V = std::variant<std::unique_ptr<int>, bool>; @@ -144,12 +143,8 @@ void test_T_assignment_sfinae() { struct X { operator void*(); }; - static_assert(!std::is_assignable<V, X>::value, - "no boolean conversion in operator="); -#ifndef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT - static_assert(std::is_assignable<V, std::false_type>::value, - "converted to bool in operator="); -#endif + static_assert(!std::is_assignable<V, X>::value, "no boolean conversion in operator="); + static_assert(std::is_assignable<V, std::false_type>::value, "converted to bool in operator="); } { struct X {}; @@ -188,7 +183,6 @@ void test_T_assignment_basic() { assert(v.index() == 1); assert(std::get<1>(v) == 43); } -#ifndef TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS { std::variant<unsigned, long> v; v = 42; @@ -198,7 +192,6 @@ void test_T_assignment_basic() { assert(v.index() == 0); assert(std::get<0>(v) == 43); } -#endif { std::variant<std::string, bool> v = true; v = "bar"; @@ -299,13 +292,11 @@ void test_T_assignment_performs_assignment() { } void test_T_assignment_vector_bool() { -#ifndef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT std::vector<bool> vec = {true}; std::variant<bool, int> v; v = vec[0]; assert(v.index() == 0); assert(std::get<0>(v) == true); -#endif } int main(int, char**) { diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp index 246309c..90e405d 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp @@ -25,18 +25,16 @@ int main(int, char**) { static_assert(!std::is_assignable<std::variant<int, int>, int>::value, ""); static_assert(!std::is_assignable<std::variant<long, long long>, int>::value, ""); - static_assert(std::is_assignable<std::variant<char>, int>::value == VariantAllowsNarrowingConversions, ""); + static_assert(!std::is_assignable<std::variant<char>, int>::value, ""); - static_assert(std::is_assignable<std::variant<std::string, float>, int>::value == VariantAllowsNarrowingConversions, ""); - static_assert(std::is_assignable<std::variant<std::string, double>, int>::value == VariantAllowsNarrowingConversions, ""); + static_assert(!std::is_assignable<std::variant<std::string, float>, int>::value, ""); + static_assert(!std::is_assignable<std::variant<std::string, double>, int>::value, ""); static_assert(!std::is_assignable<std::variant<std::string, bool>, int>::value, ""); static_assert(!std::is_assignable<std::variant<int, bool>, decltype("meow")>::value, ""); static_assert(!std::is_assignable<std::variant<int, const bool>, decltype("meow")>::value, ""); -#ifndef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT static_assert(std::is_assignable<std::variant<bool>, std::true_type>::value, ""); -#endif static_assert(!std::is_assignable<std::variant<bool>, std::unique_ptr<char> >::value, ""); static_assert(!std::is_assignable<std::variant<bool>, decltype(nullptr)>::value, ""); diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp index 89fd646..6b7de88 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp @@ -68,8 +68,7 @@ void test_T_ctor_sfinae() { } { using V = std::variant<std::string, float>; - static_assert(std::is_constructible<V, int>::value == VariantAllowsNarrowingConversions, - "no matching constructor"); + static_assert(!std::is_constructible<V, int>::value, "no matching constructor"); } { using V = std::variant<std::unique_ptr<int>, bool>; @@ -78,12 +77,8 @@ void test_T_ctor_sfinae() { struct X { operator void*(); }; - static_assert(!std::is_constructible<V, X>::value, - "no boolean conversion in constructor"); -#ifndef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT - static_assert(std::is_constructible<V, std::false_type>::value, - "converted to bool in constructor"); -#endif + static_assert(!std::is_constructible<V, X>::value, "no boolean conversion in constructor"); + static_assert(std::is_constructible<V, std::false_type>::value, "converted to bool in constructor"); } { struct X {}; @@ -128,13 +123,11 @@ void test_T_ctor_basic() { static_assert(v.index() == 1, ""); static_assert(std::get<1>(v) == 42, ""); } -#ifndef TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS { constexpr std::variant<unsigned, long> v(42); static_assert(v.index() == 1, ""); static_assert(std::get<1>(v) == 42, ""); } -#endif { std::variant<std::string, bool const> v = "foo"; assert(v.index() == 0); @@ -202,12 +195,10 @@ void test_construction_with_repeated_types() { } void test_vector_bool() { -#ifndef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT std::vector<bool> vec = {true}; std::variant<bool, int> v = vec[0]; assert(v.index() == 0); assert(std::get<0>(v) == true); -#endif } int main(int, char**) { diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/conv.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/conv.pass.cpp index 7fb44ff..0b8eeed 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/conv.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/conv.pass.cpp @@ -24,18 +24,16 @@ int main(int, char**) { static_assert(!std::is_constructible<std::variant<int, int>, int>::value, ""); static_assert(!std::is_constructible<std::variant<long, long long>, int>::value, ""); - static_assert(std::is_constructible<std::variant<char>, int>::value == VariantAllowsNarrowingConversions, ""); + static_assert(!std::is_constructible<std::variant<char>, int>::value, ""); - static_assert(std::is_constructible<std::variant<std::string, float>, int>::value == VariantAllowsNarrowingConversions, ""); - static_assert(std::is_constructible<std::variant<std::string, double>, int>::value == VariantAllowsNarrowingConversions, ""); + static_assert(!std::is_constructible<std::variant<std::string, float>, int>::value, ""); + static_assert(!std::is_constructible<std::variant<std::string, double>, int>::value, ""); static_assert(!std::is_constructible<std::variant<std::string, bool>, int>::value, ""); static_assert(!std::is_constructible<std::variant<int, bool>, decltype("meow")>::value, ""); static_assert(!std::is_constructible<std::variant<int, const bool>, decltype("meow")>::value, ""); -#ifndef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT static_assert(std::is_constructible<std::variant<bool>, std::true_type>::value, ""); -#endif static_assert(!std::is_constructible<std::variant<bool>, std::unique_ptr<char> >::value, ""); static_assert(!std::is_constructible<std::variant<bool>, decltype(nullptr)>::value, ""); diff --git a/libcxx/test/support/variant_test_helpers.h b/libcxx/test/support/variant_test_helpers.h index c174cba..345e321 100644 --- a/libcxx/test/support/variant_test_helpers.h +++ b/libcxx/test/support/variant_test_helpers.h @@ -24,16 +24,6 @@ // FIXME: Currently the variant<T&> tests are disabled using this macro. #define TEST_VARIANT_HAS_NO_REFERENCES -// TODO(LLVM-19): Remove TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS -#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT -# define TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS -#endif -#ifdef TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS -constexpr bool VariantAllowsNarrowingConversions = true; -#else -constexpr bool VariantAllowsNarrowingConversions = false; -#endif - #ifndef TEST_HAS_NO_EXCEPTIONS struct CopyThrows { CopyThrows() = default; |