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

Arjun Patel via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 1 21:39:29 PDT 2025


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

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

>From 5c135a1b2f5ca89bfb6d1c43ef17cd95c892ea82 Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 00:14:13 -0400
Subject: [PATCH 1/3] Update abs test

---
 libcxx/test/std/numerics/c.math/abs.pass.cpp | 30 +++++++++++++-------
 1 file changed, 19 insertions(+), 11 deletions(-)

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:

>From 32d133a20a41cfc936e8f8dae9f05b951692c3c9 Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 00:27:59 -0400
Subject: [PATCH 2/3] Make abs traits constexpr

---
 libcxx/include/__math/abs.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

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);
 }
 

>From c8434670860850b14a47b64e13b6680b85554b7e Mon Sep 17 00:00:00 2001
From: Arjun Patel <arjunpatel151002 at gmail.com>
Date: Wed, 2 Jul 2025 00:29:49 -0400
Subject: [PATCH 3/3] Update clang cpp23 constexpr tests

---
 .../numerics/c.math/constexpr-cxx23-clang.pass.cpp   | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

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);



More information about the libcxx-commits mailing list