Skip to content

Conversation

@frederick-vs-ja
Copy link
Contributor

Per LWG554, 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.

@frederick-vs-ja frederick-vs-ja requested a review from a team as a code owner November 6, 2025 08:16
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 6, 2025

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

Changes

Per LWG554, 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&lt;I&gt; should be false if I is a non non-promoted integer type.

Fixes #166053.


Full diff: https://github.com/llvm/llvm-project/pull/166724.diff

2 Files Affected:

  • (modified) libcxx/include/limits (+2-1)
  • (modified) libcxx/test/std/language.support/support.limits/limits/numeric.limits.members/traps.pass.cpp (+9-9)
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>();

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.
@frederick-vs-ja frederick-vs-ja force-pushed the no-promoted-no-trapping branch from 33f9f32 to cd71f86 Compare November 6, 2025 08:27
@frederick-vs-ja frederick-vs-ja merged commit e48f2be into llvm:main Nov 15, 2025
80 checks passed
@frederick-vs-ja frederick-vs-ja deleted the no-promoted-no-trapping branch November 15, 2025 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

std::numeric_limits<bool>::traps should be true

3 participants