[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