[libcxx-commits] [libcxx] [libc++] Fix UB in bitwise logic of {std, ranges}::{fill, fill_n} algorithms (PR #122410)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jan 20 13:05:37 PST 2025
================
@@ -55,6 +59,25 @@ struct __size_difference_type_traits<_Cp, __void_t<typename _Cp::difference_type
using size_type = typename _Cp::size_type;
};
+// This function is designed to operate correctly even for smaller integral types like `uint8_t`, `uint16_t`,
+// or `unsigned short`. Casting back to _StorageType is crucial to prevent undefined behavior that can arise
+// from integral promotions.
+// See https://github.com/llvm/llvm-project/pull/122410
+template <class _StoragePointer,
+ __enable_if_t<is_unsigned<typename pointer_traits<_StoragePointer>::element_type>::value, int> >
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
+__fill_masked_range(_StoragePointer __word, unsigned __ctz, unsigned __clz, bool __fill_val) {
----------------
winner245 wrote:
This makes great sense to me. I have switched the function parameters `__ctz` and `__clz` in the definition of `__fill_masked_range`. It seems that I also need to update the call-site arguments to match these two parameters, or I might have misunderstood the comment regarding the call sites. I agree with the comment's intention that this minor change could help us identify potential issues. Therefore, I also adjusted the order of the bitwise operations when calculating the mask within this function.
https://github.com/llvm/llvm-project/pull/122410
More information about the libcxx-commits
mailing list