diff --git a/libcxx/include/__math/traits.h b/libcxx/include/__math/traits.h index 4a6e58c6da8ad..00db2a8289fb3 100644 --- a/libcxx/include/__math/traits.h +++ b/libcxx/include/__math/traits.h @@ -189,6 +189,82 @@ template ::value && is_ar return __builtin_isunordered((type)__x, (type)__y); } +// MS UCRT incorrectly defines some functions in a way not working with integer types. Until C++20, this was worked +// around by -fdelayed-template-parsing. Since C++20, we can use standard feature "requires" instead. + +// TODO: Remove the workaround once UCRT fixes these functions. Note that this doesn't seem planned as of 2025-07 per +// https://developercommunity.visualstudio.com/t/10294165. + +#if defined(_LIBCPP_MSVCRT) && _LIBCPP_STD_VER >= 20 +namespace __ucrt { +template + requires is_integral_v<_A1> +[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) noexcept { + return true; +} + +template + requires is_integral_v<_A1> +[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) noexcept { + return false; +} + +template + requires is_integral_v<_A1> +[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) noexcept { + return false; +} + +template + requires is_integral_v<_A1> +[[nodiscard]] inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) noexcept { + return __x != 0; +} + +template + requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2> +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) noexcept { + using type = __promote_t<_A1, _A2>; + return __builtin_isgreater((type)__x, (type)__y); +} + +template + requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2> +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) noexcept { + using type = __promote_t<_A1, _A2>; + return __builtin_isgreaterequal((type)__x, (type)__y); +} + +template + requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2> +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) noexcept { + using type = __promote_t<_A1, _A2>; + return __builtin_isless((type)__x, (type)__y); +} + +template + requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2> +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) noexcept { + using type = __promote_t<_A1, _A2>; + return __builtin_islessequal((type)__x, (type)__y); +} + +template + requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2> +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) noexcept { + using type = __promote_t<_A1, _A2>; + return __builtin_islessgreater((type)__x, (type)__y); +} + +template + requires is_arithmetic_v<_A1> && is_arithmetic_v<_A2> +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) noexcept { + using type = __promote_t<_A1, _A2>; + return __builtin_isunordered((type)__x, (type)__y); +} +} // namespace __ucrt +#endif + } // namespace __math _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/math.h b/libcxx/include/math.h index 929bef6385043..f9e1b4ef2e352 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -427,6 +427,23 @@ using std::__math::islessgreater; using std::__math::isnan; using std::__math::isnormal; using std::__math::isunordered; +# elif _LIBCPP_STD_VER >= 20 +// MS UCRT incorrectly defines some functions in a way not working with integer types. Until C++20, this was worked +// around by -fdelayed-template-parsing. Since C++20, we can use standard feature "requires" instead. + +// TODO: Remove the workaround once UCRT fixes these functions. Note that this doesn't seem planned as of 2025-07 per +// https://developercommunity.visualstudio.com/t/10294165. + +using std::__math::__ucrt::isfinite; +using std::__math::__ucrt::isgreater; +using std::__math::__ucrt::isgreaterequal; +using std::__math::__ucrt::isinf; +using std::__math::__ucrt::isless; +using std::__math::__ucrt::islessequal; +using std::__math::__ucrt::islessgreater; +using std::__math::__ucrt::isnan; +using std::__math::__ucrt::isnormal; +using std::__math::__ucrt::isunordered; # endif // _LIBCPP_MSVCRT // We have to provide double overloads for to work on platforms that don't provide the full set of math diff --git a/libcxx/test/libcxx/fuzzing/random.pass.cpp b/libcxx/test/libcxx/fuzzing/random.pass.cpp index f0256a01f29ae..79ab7ac41151c 100644 --- a/libcxx/test/libcxx/fuzzing/random.pass.cpp +++ b/libcxx/test/libcxx/fuzzing/random.pass.cpp @@ -6,11 +6,6 @@ // //===----------------------------------------------------------------------===// -// This doesn't work on Windows because in the MSVC UCRT headers the math.h is -// actually intended to implement the full C++ spec requirements. For details -// see https://github.com/llvm/llvm-project/issues/70225#issuecomment-1992528828 -// XFAIL: msvc - // UNSUPPORTED: c++03, c++11 #include diff --git a/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp b/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp index f9f81d22ff80e..3934e5177da14 100644 --- a/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp +++ b/libcxx/test/std/depr/depr.c.headers/math_h.pass.cpp @@ -6,11 +6,6 @@ // //===----------------------------------------------------------------------===// -// This doesn't work on Windows because in the MSVC UCRT headers the math.h is -// actually intended to implement the full C++ spec requirements. For details -// see https://github.com/llvm/llvm-project/issues/70225#issuecomment-1992528828 -// XFAIL: msvc - // // GCC warns about signbit comparing `bool_v < 0`, which we're testing diff --git a/libcxx/test/std/numerics/c.math/cmath.pass.cpp b/libcxx/test/std/numerics/c.math/cmath.pass.cpp index 8d261e9fcbdb2..1f7c697784c10 100644 --- a/libcxx/test/std/numerics/c.math/cmath.pass.cpp +++ b/libcxx/test/std/numerics/c.math/cmath.pass.cpp @@ -6,11 +6,6 @@ // //===----------------------------------------------------------------------===// -// This doesn't work on Windows because in the MSVC UCRT headers the math.h is -// actually intended to implement the full C++ spec requirements. For details -// see https://github.com/llvm/llvm-project/issues/70225#issuecomment-1992528828 -// XFAIL: msvc - // #include