diff --git a/libcxx/include/__cxx03/__math/traits.h b/libcxx/include/__cxx03/__math/traits.h index 0d27680d579a4..2b6ca406ae9a0 100644 --- a/libcxx/include/__cxx03/__math/traits.h +++ b/libcxx/include/__cxx03/__math/traits.h @@ -12,7 +12,6 @@ #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> #include <__cxx03/__type_traits/is_arithmetic.h> -#include <__cxx03/__type_traits/is_floating_point.h> #include <__cxx03/__type_traits/is_integral.h> #include <__cxx03/__type_traits/is_signed.h> #include <__cxx03/__type_traits/promote.h> @@ -28,8 +27,21 @@ namespace __math { // signbit -template ::value, int> = 0> -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { +// The universal C runtime (UCRT) in the WinSDK provides floating point overloads +// for std::signbit(). By defining our overloads as templates, we can work around +// this issue as templates are less preferred than non-template functions. +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(float __x) _NOEXCEPT { + return __builtin_signbit(__x); +} + +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(double __x) _NOEXCEPT { + return __builtin_signbit(__x); +} + +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(long double __x) _NOEXCEPT { return __builtin_signbit(__x); } diff --git a/libcxx/test/std/numerics/c.math/signbit.pass.cpp b/libcxx/test/std/numerics/c.math/signbit.pass.cpp index 44ce32581cca1..7571ced2e4431 100644 --- a/libcxx/test/std/numerics/c.math/signbit.pass.cpp +++ b/libcxx/test/std/numerics/c.math/signbit.pass.cpp @@ -17,8 +17,6 @@ // GCC warns about signbit comparing `bool_v < 0`, which we're testing // ADDITIONAL_COMPILE_FLAGS(gcc): -Wno-bool-compare -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include #include #include