[libc-commits] [libc] [libc][math] Fix -Wc++23-extensions warnings in erfcf16 and erff16. (PR #215613)

via libc-commits libc-commits at lists.llvm.org
Tue Aug 11 11:47:32 PDT 2026


https://github.com/zhangweize9-cyber updated https://github.com/llvm/llvm-project/pull/215613

>From 10538d557e4e6593f5f8d8e423b765cdb034c145 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Wed, 12 Aug 2026 00:33:40 +0800
Subject: [PATCH] [libc][math] Fix -Wc++23-extensions warnings in erfcf16 and
 erff16.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Change the original logic—which directly returns a fixed value—to use `fputil::cast` for the calculation.
---
 libc/src/__support/math/erfcf16.h   |  4 ++--
 libc/src/__support/math/erff16.h    |  7 +++++--
 libc/src/math/erff16.h              |  9 +++++++++
 libc/test/src/math/erfcf16_test.cpp |  5 +++++
 libc/test/src/math/erff16_test.cpp  | 28 ++++++++++++++++++++++++++++
 5 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/libc/src/__support/math/erfcf16.h b/libc/src/__support/math/erfcf16.h
index ad096527855d5..2de95420b465b 100644
--- a/libc/src/__support/math/erfcf16.h
+++ b/libc/src/__support/math/erfcf16.h
@@ -93,7 +93,7 @@ LIBC_INLINE float16 erfcf16(float16 x) {
   }
 
   if (LIBC_UNLIKELY(x_abs == 0))
-    return 1.0f16;
+    return fputil::cast<float16>(1.0f);
 
   // Asymptotic behavior: erfc(x) rounds to 0 or 2 for |x| >= 4.0.
   if (LIBC_UNLIKELY(x_abs >= 0x4400U)) { // |x| >= 4.0
@@ -109,7 +109,7 @@ LIBC_INLINE float16 erfcf16(float16 x) {
     if (fputil::fenv_is_round_up())
       return FPBits::min_subnormal().get_val();
 #endif
-    return 0.0f16;
+    return fputil::cast<float16>(0.0f);
   }
 
   // Polynomial approximation:
diff --git a/libc/src/__support/math/erff16.h b/libc/src/__support/math/erff16.h
index 8e3a92c092e22..508d137a488d6 100644
--- a/libc/src/__support/math/erff16.h
+++ b/libc/src/__support/math/erff16.h
@@ -134,9 +134,11 @@ LIBC_INLINE float16 erff16(float16 x) {
         return x;
       }
       // Inf -> returns 1.0 or -1.0
-      return is_neg ? -1.0f16 : 1.0f16;
+      static constexpr float16 ONE_F16 = fputil::cast<float16>(1.0f);
+      return is_neg ? -ONE_F16 : ONE_F16;
     }
 
+    // FIXME: Handle f16 constant emission without triggering -Wc++23-extensions
     return fputil::cast<float16>(is_neg ? -1.0f - xf * 0x1.0p-28f
                                         : 1.0f - xf * 0x1.0p-28f);
   }
@@ -144,7 +146,8 @@ LIBC_INLINE float16 erff16(float16 x) {
   // Polynomial approximation:
   //   erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
 
-  int idx = static_cast<int>(xbits.abs().get_val() * 8.0f16);
+  static constexpr float16 EIGHT_F16 = fputil::cast<float16>(8.0f);
+  int idx = static_cast<int>(xbits.abs().get_val() * EIGHT_F16);
 
   float xsq = xf * xf;
   float x4 = xsq * xsq;
diff --git a/libc/src/math/erff16.h b/libc/src/math/erff16.h
index 922fe09df7911..d5e57f68a1c49 100644
--- a/libc/src/math/erff16.h
+++ b/libc/src/math/erff16.h
@@ -12,6 +12,15 @@
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/types.h"
 
+#ifndef float16
+#if defined(__clang__) || defined(__GNUC__)
+typedef _Float16 float16;
+#else
+#include <stdfloat>
+typedef std::float16_t float16;
+#endif
+#endif
+
 namespace LIBC_NAMESPACE_DECL {
 
 float16 erff16(float16 x);
diff --git a/libc/test/src/math/erfcf16_test.cpp b/libc/test/src/math/erfcf16_test.cpp
index d06bca5dc23a6..92262ca381aeb 100644
--- a/libc/test/src/math/erfcf16_test.cpp
+++ b/libc/test/src/math/erfcf16_test.cpp
@@ -41,3 +41,8 @@ TEST_F(LlvmLibcErfcf16Test, NegativeRange) {
                                    LIBC_NAMESPACE::erfcf16(x), 0.5);
   }
 }
+
+TEST_F(LlvmLibcErfcf16Test, NegativeValues) {
+  float16 neg_val = LIBC_NAMESPACE::float16(-1.0);
+  EXPECT_TRUE(LIBC_NAMESPACE::erfcf16(neg_val) > LIBC_NAMESPACE::float16(1.0));
+}
diff --git a/libc/test/src/math/erff16_test.cpp b/libc/test/src/math/erff16_test.cpp
index 522cc85ab15d6..7e63d760d6ea3 100644
--- a/libc/test/src/math/erff16_test.cpp
+++ b/libc/test/src/math/erff16_test.cpp
@@ -41,3 +41,31 @@ TEST_F(LlvmLibcErff16Test, NegativeRange) {
                                    LIBC_NAMESPACE::erff16(x), 0.5);
   }
 }
+
+TEST_F(LlvmLibcErff16Test, NegativeValues) {
+  float16 pos_res = LIBC_NAMESPACE::erff16(float16(1.0));
+  float16 neg_res = LIBC_NAMESPACE::erff16(float16(-1.0));
+  EXPECT_FP_EQ(neg_res, -pos_res);
+}
+
+TEST_F(LlvmLibcErff16Test, SpecialValues) {
+  EXPECT_FP_EQ(float16(1.0), LIBC_NAMESPACE::erfcf16(float16(0.0)));
+
+  float16 val_pos = float16(0.125);
+  EXPECT_TRUE(LIBC_NAMESPACE::erfcf16(val_pos) < float16(1.0));
+
+  float16 val_neg = float16(-1.0);
+  EXPECT_TRUE(LIBC_NAMESPACE::erfcf16(val_neg) > float16(1.0));
+}
+
+TEST_F(LlvmLibcErff16Test, OddFunction) {
+  EXPECT_FP_EQ(float16(0.0), LIBC_NAMESPACE::erff16(float16(0.0)));
+
+  float16 pos_input = float16(0.5);
+  float16 neg_input = float16(-0.5);
+
+  float16 pos_res = LIBC_NAMESPACE::erff16(pos_input);
+  float16 neg_res = LIBC_NAMESPACE::erff16(neg_input);
+
+  EXPECT_FP_EQ(neg_res, -pos_res);
+}



More information about the libc-commits mailing list