[libcxx-commits] [libcxx] [libc++] Fix possible out of range access in bitset (PR #121348)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 11 08:57:58 PDT 2025


winner245 wrote:

This patch is not just addressing issue for `sizeof(size_t) == 2` only. It actually addresses all cases where the ratio `sizeof(unsigned long long) / sizeof(size_t) != 1`. It also fixes several issues in the previous implementation. The previous implementation, for example `to_ullong`, already considered the cases `sizeof(unsigned long long) / sizeof(size_t) > 1`, which includes `sizeof(size_t) == 2` as a special case. However, its implementation is incorrect in that it concatenate the words with a fixed shifting amount `__bits_per_word` inside a for loop, where the correct shifting amount is `i * __bits_per_word`. Also, the previous implementation of `__bitset<1, _Size>::to_ulong` is incorrect for LLP64 with `sizeof(size_t) = 64` and `sizeof(unsigned long) = 32`, where we should throw `std::overflow_error`. 

This patch fixes the previous implementation for different scenarios with `sizeof(unsigned long long) / sizeof(size_t) != 1`. It also refactors the implementation to be more readable. Previously, the implementation was based on tag-dispatching, which is very misleading given that we have more that one tag in `to_ullong`. For example, it's really hard to understand what the different combinations of the tags `to_ullong(false_type | true_type, false_type | true_type)` mean, and we have to jump around to figure out. This patch makes it easier to read by using `constexpr if` with the conditions placed in-line. 

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


More information about the libcxx-commits mailing list