1212#include < __config>
1313#include < __type_traits/enable_if.h>
1414#include < __type_traits/is_unsigned.h>
15+ #include < climits>
1516
1617#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1718# pragma GCC system_header
@@ -25,20 +26,18 @@ class __bit_iterator;
2526template <class , class = void >
2627struct __size_difference_type_traits ;
2728
29+ // This function is designed to operate correctly even for smaller integral types like `uint8_t`, `uint16_t`,
30+ // or `unsigned short`. Casting back to _StorageType is crucial to prevent undefined behavior that can arise
31+ // from integral promotions.
32+ // See https://github.com/llvm/llvm-project/pull/122410
2833template <class _StorageType , __enable_if_t <is_unsigned<_StorageType>::value, int > = 0 >
29- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __leading_mask (unsigned __shift) {
30- return static_cast <_StorageType>(static_cast <_StorageType>(~static_cast <_StorageType>(0 )) << __shift);
31- }
32-
33- template <class _StorageType , __enable_if_t <is_unsigned<_StorageType>::value, int > = 0 >
34- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __trailing_mask (unsigned __shift) {
35- return static_cast <_StorageType>(static_cast <_StorageType>(~static_cast <_StorageType>(0 )) >> __shift);
36- }
37-
38- template <class _StorageType , __enable_if_t <is_unsigned<_StorageType>::value, int > = 0 >
39- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __middle_mask (unsigned __lshift, unsigned __rshift) {
40- return static_cast <_StorageType>(
41- std::__leading_mask<_StorageType>(__lshift) & std::__trailing_mask<_StorageType>(__rshift));
34+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _StorageType
35+ __fill_range_in_word (_StorageType __word, unsigned __ctz, unsigned __clz, bool __fill_val) {
36+ _LIBCPP_ASSERT_VALID_INPUT_RANGE (
37+ __ctz + __clz < sizeof (_StorageType) * CHAR_BIT, " __fill_range called with invalid range" );
38+ _StorageType __m = static_cast <_StorageType>(static_cast <_StorageType>(~static_cast <_StorageType>(0 )) << __ctz) &
39+ static_cast <_StorageType>(static_cast <_StorageType>(~static_cast <_StorageType>(0 )) >> __clz);
40+ return __fill_val ? __word | __m : __word & ~__m;
4241}
4342
4443_LIBCPP_END_NAMESPACE_STD
0 commit comments