diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2025-05-16 13:05:51 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2025-05-27 12:11:43 +0100 |
commit | e0c3066c14ad98d130ddd1183be3caaeea19c63b (patch) | |
tree | d89f56e019aca6bee8ab5028bab18b12a02425fc | |
parent | 351e60095cfaa73b5ac69222d00e0cd4ae5725d4 (diff) | |
download | gcc-e0c3066c14ad98d130ddd1183be3caaeea19c63b.zip gcc-e0c3066c14ad98d130ddd1183be3caaeea19c63b.tar.gz gcc-e0c3066c14ad98d130ddd1183be3caaeea19c63b.tar.bz2 |
libstdc++: Support std::abs for 128-bit integers and floats [PR96710]
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.
Reviewed-by: Tomasz KamiĆski <tkaminsk@redhat.com>
-rw-r--r-- | libstdc++-v3/include/bits/std_abs.h | 9 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/headers/cmath/82644.cc | 3 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/headers/cstdlib/abs128.cc | 16 |
3 files changed, 26 insertions, 2 deletions
diff --git a/libstdc++-v3/include/bits/std_abs.h b/libstdc++-v3/include/bits/std_abs.h index 35ec4d3..3d805e6 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 3274f05..40abb2c 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 0000000..cfb0562 --- /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 |