Fix non-portable use of std::abs(double) in constexpr function
authorJonathan Wakely <jwakely@redhat.com>
Tue, 25 Jun 2019 13:18:36 +0000 (14:18 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 25 Jun 2019 13:18:36 +0000 (14:18 +0100)
Although libstdc++ adds 'constexpr' to its std::abs(floating-point)
overloads (as a non-conforming extension), those overloads are not used
if the target libc provides them, which is the case on Solaris.

The fix is to avoid std::abs and simply apply the negation when needed.

* include/std/numeric (midpoint(T, T)): Avoid std::abs in constexpr
function.

From-SVN: r272653

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/numeric

index d7392553901f74a51b64d3528f2f5815e3dc5873..7222810984dfc71ede58dfe35bfb41d9f49bff45 100644 (file)
@@ -1,3 +1,8 @@
+2019-06-25  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/std/numeric (midpoint(T, T)): Avoid std::abs in constexpr
+       function.
+
 2019-06-25  Jakub Jelinek  <jakub@redhat.com>
 
        * include/pstl/pstl_config.h (_PSTL_PRAGMA_SIMD_SCAN,
index af6844697699132f507f04ec64d3016db64412f7..2f9462183dda986cd363b1f08d1cdaba648f309c 100644 (file)
@@ -162,7 +162,6 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
 #if __cplusplus > 201703L
 #include <limits>
-#include <bits/std_abs.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -196,11 +195,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        {
          constexpr _Tp __lo = numeric_limits<_Tp>::min() * 2;
          constexpr _Tp __hi = numeric_limits<_Tp>::max() / 2;
-         if (std::abs(__a) <= __hi && std::abs(__b) <= __hi) [[likely]]
+         const _Tp __abs_a = __a < 0 ? -__a : __a;
+         const _Tp __abs_b = __b < 0 ? -__b : __b;
+         if (__abs_a <= __hi && __abs_b <= __hi) [[likely]]
            return (__a + __b) / 2; // always correctly rounded
-         if (std::abs(__a) < __lo) // not safe to halve __a
+         if (__abs_a < __lo) // not safe to halve __a
            return __a + __b/2;
-         if (std::abs(__b) < __lo) // not safe to halve __b
+         if (__abs_b < __lo) // not safe to halve __b
            return __a/2 + __b;
          return __a/2 + __b/2;     // otherwise correctly rounded
        }