[libcxx-commits] [libcxx] [libcxx][test] Stop testing signaling NaN in the constexpr comparison functions (PR #222542)

Cyrus Ding via libcxx-commits libcxx-commits at lists.llvm.org
Thu Sep 10 01:12:30 PDT 2026


https://github.com/dingcyrus created https://github.com/llvm/llvm-project/pull/222542

std::isgreater, std::isgreaterequal, std::islessequal and std::isunordered behave like the corresponding C macros, which may raise the "invalid" floating-point exception when an operand is a signaling NaN ([c.math.fpclass]/1, C23 7.12.17). Raising a floating-point exception is not allowed during constant evaluation, so passing signaling_NaN() to these functions in a constexpr context is bogus; MSVC's implementation rejects it.

Remove the signaling NaN asserts from the four affected tests. The classification functions (isnan, isinf, fpclassify, ...) are affected: the standard guarantees they never raise for signaling NaN, so their existing sNaN tests remain valid.

Fixes #222431

>From 45dad83a24fddb86be805a41b930664264f96740 Mon Sep 17 00:00:00 2001
From: Cyrus Ding <785101675 at qq.com>
Date: Thu, 10 Sep 2026 16:09:51 +0800
Subject: [PATCH] [libcxx][test] Stop testing signaling NaN in the constexpr
 comparison functions

  std::isgreater, std::isgreaterequal, std::islessequal and std::isunordered
  behave like the corresponding C macros, which may raise the "invalid"
  floating-point exception when an operand is a signaling NaN ([c.math.fpclass]/1,
  C23 7.12.17). Raising a floating-point exception is not allowed during constant
  evaluation, so passing signaling_NaN() to these functions in a constexpr context
  is bogus; MSVC's implementation rejects it.

  Remove the signaling NaN asserts from the four affected tests. The
  classification functions (isnan, isinf, fpclassify, ...) are unaffected: the
  standard guarantees they never raise for signaling NaN, so their existing
  sNaN tests remain valid.

  Fixes #222431
---
 libcxx/test/std/numerics/c.math/isgreater.pass.cpp      | 3 ++-
 libcxx/test/std/numerics/c.math/isgreaterequal.pass.cpp | 3 ++-
 libcxx/test/std/numerics/c.math/islessequal.pass.cpp    | 3 ++-
 libcxx/test/std/numerics/c.math/isunordered.pass.cpp    | 3 ++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/libcxx/test/std/numerics/c.math/isgreater.pass.cpp b/libcxx/test/std/numerics/c.math/isgreater.pass.cpp
index e09680edf50e1..31ba3d03dd87f 100644
--- a/libcxx/test/std/numerics/c.math/isgreater.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isgreater.pass.cpp
@@ -32,7 +32,8 @@ struct TestFloat {
     assert(!std::isgreater(lim::quiet_NaN(), T(0)));
     assert(!std::isgreater(T(0), lim::quiet_NaN()));
     assert(!std::isgreater(lim::quiet_NaN(), lim::quiet_NaN()));
-    assert(!std::isgreater(lim::signaling_NaN(), T(0)));
+    // Note: signaling NaN is intentionally not tested. Passing a signaling NaN to these macros may
+    // raise the "invalid" floating-point exception, which is not allowed during constant evaluation.
   }
 };
 
diff --git a/libcxx/test/std/numerics/c.math/isgreaterequal.pass.cpp b/libcxx/test/std/numerics/c.math/isgreaterequal.pass.cpp
index a1f03253247ca..f28e6139c3991 100644
--- a/libcxx/test/std/numerics/c.math/isgreaterequal.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isgreaterequal.pass.cpp
@@ -31,7 +31,8 @@ struct TestFloat {
 
     assert(!std::isgreaterequal(lim::quiet_NaN(), T(0)));
     assert(!std::isgreaterequal(T(0), lim::quiet_NaN()));
-    assert(!std::isgreaterequal(lim::signaling_NaN(), T(0)));
+    // Note: signaling NaN is intentionally not tested. Passing a signaling NaN to these macros may
+    // raise the "invalid" floating-point exception, which is not allowed during constant evaluation.
   }
 };
 
diff --git a/libcxx/test/std/numerics/c.math/islessequal.pass.cpp b/libcxx/test/std/numerics/c.math/islessequal.pass.cpp
index 34b5cacd584e5..1fd590217788f 100644
--- a/libcxx/test/std/numerics/c.math/islessequal.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/islessequal.pass.cpp
@@ -31,7 +31,8 @@ struct TestFloat {
 
     assert(!std::islessequal(lim::quiet_NaN(), T(0)));
     assert(!std::islessequal(T(0), lim::quiet_NaN()));
-    assert(!std::islessequal(lim::signaling_NaN(), T(0)));
+    // Note: signaling NaN is intentionally not tested. Passing a signaling NaN to these macros may
+    // raise the "invalid" floating-point exception, which is not allowed during constant evaluation.
   }
 };
 
diff --git a/libcxx/test/std/numerics/c.math/isunordered.pass.cpp b/libcxx/test/std/numerics/c.math/isunordered.pass.cpp
index bb13d46768a69..79cc56c50a5ca 100644
--- a/libcxx/test/std/numerics/c.math/isunordered.pass.cpp
+++ b/libcxx/test/std/numerics/c.math/isunordered.pass.cpp
@@ -27,8 +27,9 @@ struct TestFloat {
     assert(std::isunordered(lim::quiet_NaN(), T(0)));
     assert(std::isunordered(T(0), lim::quiet_NaN()));
     assert(std::isunordered(lim::quiet_NaN(), lim::quiet_NaN()));
+    // Note: signaling NaN is intentionally not tested. Passing a signaling NaN to these macros may
+    // raise the "invalid" floating-point exception, which is not allowed during constant evaluation.
 
-    assert(std::isunordered(lim::signaling_NaN(), T(0)));
     assert(!std::isunordered(lim::infinity(), lim::infinity()));
     assert(!std::isunordered(lim::max(), lim::lowest()));
   }



More information about the libcxx-commits mailing list