On Fri, May 23, 2025 at 6:58 PM Jonathan Wakely <[email protected]> wrote:
> 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).
>
LGTM.
>
> 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
>
>