Currently we only provide std::abs(__int128) and std::abs(__float128) for non-strict modes, i.e. -std=gnu++NN but not -std=c++NN.
This defines those overloads for strict modes too, as a small step towards resolving PR 96710 (which will eventually mean that __int128 satisfies the std::integral concept). libstdc++-v3/ChangeLog: PR libstdc++/96710 * include/bits/std_abs.h [__SIZEOF_INT128__] (abs(__int128)): Define. [_GLIBCXX_USE_FLOAT128] (abs(__float128)): Enable definition for strict modes. * testsuite/26_numerics/headers/cmath/82644.cc: Use strict_std instead of defining __STRICT_ANSI__. * testsuite/26_numerics/headers/cstdlib/abs128.cc: New test. --- Even before we make std::is_integral_v<__int128> true, I don't see why we can't overload std::abs for it. Likewise for __float128. Tested x86_64-linux and sparc-solaris11.3 (-m32 and -m64 for both). libstdc++-v3/include/bits/std_abs.h | 9 ++++++++- .../testsuite/26_numerics/headers/cmath/82644.cc | 3 ++- .../26_numerics/headers/cstdlib/abs128.cc | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 libstdc++-v3/testsuite/26_numerics/headers/cstdlib/abs128.cc diff --git a/libstdc++-v3/include/bits/std_abs.h b/libstdc++-v3/include/bits/std_abs.h index 35ec4d374b6e..3d805e6d6f04 100644 --- a/libstdc++-v3/include/bits/std_abs.h +++ b/libstdc++-v3/include/bits/std_abs.h @@ -103,6 +103,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; } #endif +#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ + // In strict modes __GLIBCXX_TYPE_INT_N_0 is not defined for __int128, + // but we want to always define std::abs(__int128). + __extension__ inline _GLIBCXX_CONSTEXPR __int128 + abs(__int128 __x) { return __x >= 0 ? __x : -__x; } +#endif + #if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) constexpr _Float16 abs(_Float16 __x) @@ -137,7 +144,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __gnu_cxx::__bfloat16_t(__builtin_fabsf(__x)); } #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) +#if defined(_GLIBCXX_USE_FLOAT128) __extension__ inline _GLIBCXX_CONSTEXPR __float128 abs(__float128 __x) diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/82644.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/82644.cc index 3274f0564c4d..40abb2ced668 100644 --- a/libstdc++-v3/testsuite/26_numerics/headers/cmath/82644.cc +++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/82644.cc @@ -15,8 +15,9 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__ -D__STRICT_ANSI__" } +// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" } // { dg-do compile { target c++11 } } +// // { dg-add-options strict_std } #define conf_hyperg 1 #define conf_hypergf 2 diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/abs128.cc b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/abs128.cc new file mode 100644 index 000000000000..cfb056219b29 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/abs128.cc @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-add-options strict_std } + +#include <cstdlib> + +template<typename T> T same_type(T, T) { return T(); } + +#ifdef __SIZEOF_INT128__ +__int128 i = 0; +__int128 j = same_type(std::abs(i), i); +#endif + +#ifdef __SIZEOF_FLOAT128__ +__float128 f = 0.0; +__float128 g = same_type(std::abs(f), f); +#endif -- 2.49.0