[libcxx-commits] [libcxx] [libc++] Fix possible out of range access in bitset::to_ullong implementation (PR #121348)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 2 05:59:53 PST 2025
================
@@ -381,8 +382,9 @@ __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);
+ size_t __n_words = std::min<size_t>(_N_words, sizeof(unsigned long long) / sizeof(__storage_type));
----------------
winner245 wrote:
I have revised the code and added support for 16-bit systems. Specifically, I modified the ULL ctor and the `to_ullong` and `to_ulong` functions. The ULL ctor is a bit ugly because we now need to consider `sizeof(unsigned long long) / sizeof(size_t) == 4` combined with the possibility of `_N_words < 4`. This added complexity could be well integrated into a cleaner loop as done in the `to_ullong` function. However, constexpr loops are not supported in C++11, and the standard requires this ctor to be constexpr since C++11. The implementations of the `to_ullong` and `to_ulong` functions are much cleaner and valid for a wider range of platforms with any different ratio values `sizeof(unsigned long long) / sizeof(size_t)`.
Currently, I am encountering a CI failure from the Python script `libcxx/utils/gdb/libcxx/printers.py`, which reports:
> gdb.error: There is no member or method named __bits_per_word.
> {<std::__1::__bitset<1, 15>> = {__first_ = 1020}, static __n_words = 1}
It is a gdb test initiated by `libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp`, which calls `StdBitsetPrinter::__init__` in `libcxx/utils/gdb/libcxx/printers.py` and encountered the failure while executing line 396 `self.bits_per_word = int(self.val["__bits_per_word"])`. I couldn't figure out what may have caused this failure as I didn't touch `__bits_per_word`. The `__bits_per_word` is a static data member in the base class `__bitset<_N_words, _Size>` and its specializations `__bitset<1, _Size>` and `__bitset<0, 0>`. Do you have any idea what might be causing this error?
https://github.com/llvm/llvm-project/pull/121348
More information about the libcxx-commits
mailing list