[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