[libcxx-commits] [libcxx] [libc++] Make `std::numeric_limits<NonPromoted>::traps` `false` (PR #166724)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Nov 6 00:16:30 PST 2025
https://github.com/frederick-vs-ja created https://github.com/llvm/llvm-project/pull/166724
Per [LWG554](https://cplusplus.github.io/LWG/issue554), the rationale is that even if `true / false` traps, the values causing trap are the converted `int` values produced by usual arithmetic conversion, but not the original `bool` values.
This is also true for all other non-promoted integer types. As a result, `std::numeric_limits<I>` should be `false` if `I` is a non non-promoted integer type.
Fixes #166053.
>From 33f9f32584b59331215a15220d1f1299c7f3f2d7 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Thu, 6 Nov 2025 16:14:46 +0800
Subject: [PATCH] [libc++] Make `std::numeric_limits<NonPromoted>::traps`
`false`
Per [LWG554](https://cplusplus.github.io/LWG/issue554), the rationale is
that even if `true / false` traps, the values causing trap are the
converted `int` values produced by usual arithmetic conversion, but not
the original `bool` values.
This is also true for all other non-promoted integer types. As a result,
`std::numeric_limits<I>` should be `false` if `I` is a non non-promoted
integer type.
---
libcxx/include/limits | 3 ++-
.../numeric.limits.members/traps.pass.cpp | 18 +++++++++---------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/limits b/libcxx/include/limits
index e8581cf9c321d..ae93fcd7164fd 100644
--- a/libcxx/include/limits
+++ b/libcxx/include/limits
@@ -107,6 +107,7 @@ template<> class numeric_limits<cv long double>;
#else
# include <__config>
# include <__type_traits/is_arithmetic.h>
+# include <__type_traits/is_same.h>
# include <__type_traits/is_signed.h>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -220,7 +221,7 @@ protected:
static _LIBCPP_CONSTEXPR const bool is_modulo = !std::is_signed<_Tp>::value;
# if defined(__i386__) || defined(__x86_64__) || defined(__wasm__)
- static _LIBCPP_CONSTEXPR const bool traps = true;
+ static _LIBCPP_CONSTEXPR const bool traps = is_same<decltype(+_Tp(0)), _Tp>::value;
# else
static _LIBCPP_CONSTEXPR const bool traps = false;
# endif
diff --git a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
index 66e149bf58d1b..f90bdfea7dcad 100644
--- a/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp
@@ -33,17 +33,17 @@ test()
int main(int, char**)
{
test<bool, false>();
- test<char, integral_types_trap>();
- test<signed char, integral_types_trap>();
- test<unsigned char, integral_types_trap>();
- test<wchar_t, integral_types_trap>();
+ test<char, false>();
+ test<signed char, false>();
+ test<unsigned char, false>();
+ test<wchar_t, false>();
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
- test<char8_t, integral_types_trap>();
+ test<char8_t, false>();
#endif
- test<char16_t, integral_types_trap>();
- test<char32_t, integral_types_trap>();
- test<short, integral_types_trap>();
- test<unsigned short, integral_types_trap>();
+ test<char16_t, false>();
+ test<char32_t, false>();
+ test<short, false>();
+ test<unsigned short, false>();
test<int, integral_types_trap>();
test<unsigned int, integral_types_trap>();
test<long, integral_types_trap>();
More information about the libcxx-commits
mailing list