diff --git a/libcxx/include/__math/traits.h b/libcxx/include/__math/traits.h index 27ec52ecef02..35c283cc9e21 100644 --- a/libcxx/include/__math/traits.h +++ b/libcxx/include/__math/traits.h @@ -79,20 +79,22 @@ _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf return false; } -#ifdef _LIBCPP_PREFERRED_OVERLOAD _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { return __builtin_isinf(__x); } -_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool -isinf(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI +#ifdef _LIBCPP_PREFERRED_OVERLOAD +_LIBCPP_PREFERRED_OVERLOAD +#endif + bool + isinf(double __x) _NOEXCEPT { return __builtin_isinf(__x); } _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { return __builtin_isinf(__x); } -#endif // isnan @@ -106,20 +108,22 @@ _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan return false; } -#ifdef _LIBCPP_PREFERRED_OVERLOAD _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { return __builtin_isnan(__x); } -_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool -isnan(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI +#ifdef _LIBCPP_PREFERRED_OVERLOAD +_LIBCPP_PREFERRED_OVERLOAD +#endif + bool + isnan(double __x) _NOEXCEPT { return __builtin_isnan(__x); } _LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { return __builtin_isnan(__x); } -#endif // isnormal diff --git a/libcxx/test/std/numerics/c.math/cmath.pass.cpp b/libcxx/test/std/numerics/c.math/cmath.pass.cpp index 6028aa5a2110..34c30fb998f4 100644 --- a/libcxx/test/std/numerics/c.math/cmath.pass.cpp +++ b/libcxx/test/std/numerics/c.math/cmath.pass.cpp @@ -708,15 +708,16 @@ void test_isinf() static_assert((std::is_same::value), ""); typedef decltype(std::isinf((double)0)) DoubleRetType; -#if !defined(__linux__) || defined(__clang__) - static_assert((std::is_same::value), ""); -#else +#if defined(__GLIBC__) && TEST_STD_VER == 03 && defined(TEST_COMPILER_CLANG) // GLIBC < 2.23 defines 'isinf(double)' with a return type of 'int' in // all C++ dialects. The test should tolerate this when libc++ can't work - // around it. + // around it via `_LIBCPP_PREFERRED_OVERLOAD`, which is only available + // in modern versions of Clang, and not elsewhere. // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439 static_assert((std::is_same::value || std::is_same::value), ""); +#else + static_assert((std::is_same::value), ""); #endif static_assert((std::is_same::value), ""); @@ -794,15 +795,16 @@ void test_isnan() static_assert((std::is_same::value), ""); typedef decltype(std::isnan((double)0)) DoubleRetType; -#if !defined(__linux__) || defined(__clang__) - static_assert((std::is_same::value), ""); -#else - // GLIBC < 2.23 defines 'isinf(double)' with a return type of 'int' in +#if defined(__GLIBC__) && TEST_STD_VER == 03 && defined(TEST_COMPILER_CLANG) + // GLIBC < 2.23 defines 'isnan(double)' with a return type of 'int' in // all C++ dialects. The test should tolerate this when libc++ can't work - // around it. + // around it via `_LIBCPP_PREFERRED_OVERLOAD`, which is only available + // in modern versions of Clang, and not elsewhere. // See: https://sourceware.org/bugzilla/show_bug.cgi?id=19439 static_assert((std::is_same::value || std::is_same::value), ""); +#else + static_assert((std::is_same::value), ""); #endif static_assert((std::is_same::value), ""); diff --git a/libcxx/test/std/numerics/c.math/isinf.pass.cpp b/libcxx/test/std/numerics/c.math/isinf.pass.cpp index e935b53187fe..e5169e8056c2 100644 --- a/libcxx/test/std/numerics/c.math/isinf.pass.cpp +++ b/libcxx/test/std/numerics/c.math/isinf.pass.cpp @@ -62,9 +62,21 @@ struct TestInt { } }; +template +struct ConvertibleTo { + operator T() const { return T(); } +}; + int main(int, char**) { types::for_each(types::floating_point_types(), TestFloat()); types::for_each(types::integral_types(), TestInt()); + // Make sure we can call `std::isinf` with convertible types + { + assert(!std::isinf(ConvertibleTo())); + assert(!std::isinf(ConvertibleTo())); + assert(!std::isinf(ConvertibleTo())); + } + return 0; } diff --git a/libcxx/test/std/numerics/c.math/isnan.pass.cpp b/libcxx/test/std/numerics/c.math/isnan.pass.cpp index fffb12464586..e4ccab1243e5 100644 --- a/libcxx/test/std/numerics/c.math/isnan.pass.cpp +++ b/libcxx/test/std/numerics/c.math/isnan.pass.cpp @@ -62,9 +62,21 @@ struct TestInt { } }; +template +struct ConvertibleTo { + operator T() const { return T(); } +}; + int main(int, char**) { types::for_each(types::floating_point_types(), TestFloat()); types::for_each(types::integral_types(), TestInt()); + // Make sure we can call `std::isnan` with convertible types + { + assert(!std::isnan(ConvertibleTo())); + assert(!std::isnan(ConvertibleTo())); + assert(!std::isnan(ConvertibleTo())); + } + return 0; }