[libcxx-commits] [libcxx] [libc++] Fix ambiguous call in {ranges, std}::find (PR #122641)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 11 20:55:16 PST 2025
================
@@ -62,6 +63,20 @@ struct __size_difference_type_traits<_Cp, __void_t<typename _Cp::difference_type
using size_type = typename _Cp::size_type;
};
+template <class _StorageType>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __trailing_mask(unsigned __clz) {
+ static_assert(is_unsigned<_StorageType>::value, "__trailing_mask only works with unsigned types");
+ return static_cast<_StorageType>(static_cast<_StorageType>(~static_cast<_StorageType>(0)) >> __clz);
+}
+
+template <class _StorageType>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __middle_mask(unsigned __clz, unsigned __ctz) {
+ static_assert(is_unsigned<_StorageType>::value, "__middle_mask only works with unsigned types");
+ return static_cast<_StorageType>(
----------------
winner245 wrote:
The bitwise operators for small integral types (whose width is less than `sizeof(int)`) are subject to integral promotions, leading to UB or ambiguities before C++20. For example, the bitwise not operator `~` applied on a small unsigned integral would become a negative `int` value due to integral promotion, and the subsequent left shift `<<` of a negative value result in UB before C++20 (refer to [cppreference](https://en.cppreference.com/w/cpp/language/operator_arithmetic#Built-in_bitwise_shift_operators)). Therefore, to ensure that we do not trigger any UB, we should ensure that every intermediate result of the bitwise operation involving the small integral types is cast back to the unsigned `__storage_type`.
https://github.com/llvm/llvm-project/pull/122641
More information about the libcxx-commits
mailing list