[libcxx-commits] [libcxx] [libc++] Improve bitset::to_ullong Implementation (PR #121348)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Mon Dec 30 09:21:43 PST 2024


https://github.com/winner245 created https://github.com/llvm/llvm-project/pull/121348

This PR modifies the `to_ullong` method in the `bitset` class to enhance its functionality and correctness across a wider range of system architectures. The current implementation of `__bitset::to_ullong(true_type, true_type)` only considers scenarios where `sizeof(unsigned long long) / sizeof(std::size_t) <= 2`. This limitation can lead to incorrect concatenation of words into `unsigned long long` (ULL) for systems where `sizeof(unsigned long long) / sizeof(std::size_t) > 2`. 

The C++ standard specifies the minimum bit widths for `std::size_t`  and `unsigned long long` (ULL) as follows:

| Type                 | Minimum bit width |
|----------------------|-------------------|
| `std::size_t`        | 16                |
| `unsigned long long` | 64                |


It is possible for `sizeof(ULL) / sizeof(std::size_t) > 2` in certain environments (such as 16-bit systems). However, the current implementations did not account for these scenarios, which are addressed in this PR.  

>From 4d20d1e0d126444397e63b6a603f1dafe964b7c4 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 30 Dec 2024 12:19:19 -0500
Subject: [PATCH] Improve bitset::to_ullong Implementation

---
 libcxx/include/bitset | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 919d2a0f07e096..edf017897870d0 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -381,8 +381,8 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
   unsigned long long __r = __first_[0];
   _LIBCPP_DIAGNOSTIC_PUSH
   _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
-  for (size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i)
-    __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT);
+  for (size_t __i = 1; __i < _N_words; ++__i)
+    __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
   _LIBCPP_DIAGNOSTIC_POP
   return __r;
 }



More information about the libcxx-commits mailing list