[libcxx-commits] [libcxx] [libc++][math] Add constexpr for std::abs() (PR #146633)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 1 21:40:16 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Arjun Patel (arjunUpatel)

<details>
<summary>Changes</summary>

Implement `constexpr` for `std::abs()` as defined by [P0533R9](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0533r9.pdf) (new C++23 feature). Progress tracked by #<!-- -->105174

---
Full diff: https://github.com/llvm/llvm-project/pull/146633.diff


3 Files Affected:

- (modified) libcxx/include/__math/abs.h (+6-6) 
- (modified) libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp (+6-6) 
- (modified) libcxx/test/std/numerics/c.math/abs.pass.cpp (+19-11) 


``````````diff
diff --git a/libcxx/include/__math/abs.h b/libcxx/include/__math/abs.h
index b780159f11ebf..a1d5854ac8878 100644
--- a/libcxx/include/__math/abs.h
+++ b/libcxx/include/__math/abs.h
@@ -41,25 +41,25 @@ template <class _A1, __enable_if_t<is_integral<_A1>::value, int> = 0>
 
 // abs
 
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline float abs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); }
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline double abs(double __x) _NOEXCEPT { return __builtin_fabs(__x); }
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline float abs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); }
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline double abs(double __x) _NOEXCEPT { return __builtin_fabs(__x); }
 
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long double abs(long double __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long double abs(long double __x) _NOEXCEPT {
   return __builtin_fabsl(__x);
 }
 
 template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline int abs(int __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline int abs(int __x) _NOEXCEPT {
   return __builtin_abs(__x);
 }
 
 template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long abs(long __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long abs(long __x) _NOEXCEPT {
   return __builtin_labs(__x);
 }
 
 template <class = int>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI inline long long abs(long long __x) _NOEXCEPT {
+[[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline long long abs(long long __x) _NOEXCEPT {
   return __builtin_llabs(__x);
 }
 
diff --git a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
index 3f17f21e8c108..64164240c8564 100644
--- a/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
+++ b/libcxx/test/libcxx/numerics/c.math/constexpr-cxx23-clang.pass.cpp
@@ -40,12 +40,12 @@ int main(int, char**) {
   double DummyDouble;
   long double DummyLongDouble;
 
-  ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1) == 1);
-  ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
-  ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
-  ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
-  ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
-  ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+  ASSERT_CONSTEXPR_CXX23(std::abs(-1) == 1);
+  ASSERT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+  ASSERT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+  ASSERT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+  ASSERT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+  ASSERT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
 
   ASSERT_NOT_CONSTEXPR_CXX23(std::labs(-1L) == 1L);
   ASSERT_NOT_CONSTEXPR_CXX23(std::llabs(-1LL) == 1LL);
diff --git a/libcxx/test/std/numerics/c.math/abs.pass.cpp b/libcxx/test/std/numerics/c.math/abs.pass.cpp
index 51aee6e986836..908620b2a3290 100644
--- a/libcxx/test/std/numerics/c.math/abs.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/abs.pass.cpp
@@ -20,21 +20,29 @@ struct correct_size_int {
 };
 
 template <class Source, class Result>
-void test_abs() {
-  Source neg_val = -5;
-  Source pos_val = 5;
-  Result res     = 5;
+TEST_CONSTEXPR_CXX23 void test_abs() {
+  TEST_CONSTEXPR_CXX23 Source neg_val = -5;
+  TEST_CONSTEXPR_CXX23 Source pos_val = 5;
+  TEST_CONSTEXPR_CXX23 Result res     = 5;
 
   ASSERT_SAME_TYPE(decltype(std::abs(neg_val)), Result);
-
-  assert(std::abs(neg_val) == res);
-  assert(std::abs(pos_val) == res);
+  #if TEST_STD_VER >= 23
+    static_assert(std::abs(neg_val) == res);
+    static_assert(std::abs(pos_val) == res);
+  #else 
+    assert(std::abs(neg_val) == res);
+    assert(std::abs(pos_val) == res);
+  #endif
 }
 
-void test_big() {
-  long long int big_value          = std::numeric_limits<long long int>::max(); // a value too big for ints to store
-  long long int negative_big_value = -big_value;
-  assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+TEST_CONSTEXPR_CXX23 void test_big() {
+  TEST_CONSTEXPR_CXX23 long long int big_value          = std::numeric_limits<long long int>::max(); // a value too big for ints to store
+  TEST_CONSTEXPR_CXX23 long long int negative_big_value = -big_value;
+  #if TEST_STD_VER >= 23
+    static_assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+  #else
+    assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
+  #endif
 }
 
 // The following is helpful to keep in mind:

``````````

</details>


https://github.com/llvm/llvm-project/pull/146633


More information about the libcxx-commits mailing list