From 39f581028c76ebfc94a5c2714f43c9e56089a9b0 Mon Sep 17 00:00:00 2001 From: Matthias Kretz Date: Tue, 18 Jan 2022 17:04:06 +0100 Subject: libstdc++: Fix for non-constexpr math_errhandling Use SFINAE magic to support: "It is unspecified whether math_errhandling is a macro or an identifier with external linkage." [C Standard] Signed-off-by: Matthias Kretz libstdc++-v3/ChangeLog: * include/experimental/bits/simd.h (__floating_point_flags): Do not rely on math_errhandling to expand to a constant expression. --- libstdc++-v3/include/experimental/bits/simd.h | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'libstdc++-v3') diff --git a/libstdc++-v3/include/experimental/bits/simd.h b/libstdc++-v3/include/experimental/bits/simd.h index c991e3f..82e9841 100644 --- a/libstdc++-v3/include/experimental/bits/simd.h +++ b/libstdc++-v3/include/experimental/bits/simd.h @@ -283,20 +283,34 @@ constexpr inline bool __have_power_vmx = __have_power_vsx; namespace __detail { - constexpr bool __handle_fpexcept = #ifdef math_errhandling - math_errhandling & MATH_ERREXCEPT; -#elif defined __FAST_MATH__ - false; + // Determines _S_handle_fpexcept from math_errhandling if it is defined and expands to a constant + // expression. math_errhandling may expand to an extern symbol, in which case a constexpr value + // must be guessed. + template + constexpr bool __handle_fpexcept_impl(int) + { return math_errhandling & MATH_ERREXCEPT; } +#endif + + // Fallback if math_errhandling doesn't work: with fast-math assume floating-point exceptions are + // ignored, otherwise implement correct exception behavior. + constexpr bool __handle_fpexcept_impl(float) + { +#if defined __FAST_MATH__ + return false; #else - true; + return true; #endif + } + + /// True if math functions must raise floating-point exceptions as specified by C17. + static constexpr bool _S_handle_fpexcept = __handle_fpexcept_impl(0); constexpr std::uint_least64_t __floating_point_flags() { std::uint_least64_t __flags = 0; - if constexpr (__handle_fpexcept) + if constexpr (_S_handle_fpexcept) __flags |= 1; #ifdef __FAST_MATH__ __flags |= 1 << 1; -- cgit v1.1