[libc-commits] [libc] [libc][memory_utils] Rename shadowed load/store to avoid ADL ambiguity (PR #211714)
Jackson Stogel via libc-commits
libc-commits at lists.llvm.org
Thu Jul 23 21:19:58 PDT 2026
https://github.com/jtstogel updated https://github.com/llvm/llvm-project/pull/211714
>From 5cac910caef3ec96a997b6188542fb35502be7ed Mon Sep 17 00:00:00 2001
From: jtstogel <jtstogel at gmail.com>
Date: Thu, 23 Jul 2026 17:12:53 -0700
Subject: [PATCH] [libc][memory_utils] Rename shadowed load/store to avoid ADL
ambiguity
When compiling with MSVC for non-x86 architectures, `op_generic.h` picks a non-builtin type for generic_v128 and friends: https://github.com/llvm/llvm-project/blob/cad3c95a89c48d714a71f6e8b4af6f3e3ab100ea/libc/src/string/memory_utils/op_generic.h#L54-L57
This means calls to `load` and `store` trigger ADL with the `load` definition in `memory_utils/utils.h` as the other candidate.
---
libc/src/string/memory_utils/op_generic.h | 6 +++---
libc/src/string/memory_utils/utils.h | 10 +++++-----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/libc/src/string/memory_utils/op_generic.h b/libc/src/string/memory_utils/op_generic.h
index a86cbd8bcfc72..670ef085f9dee 100644
--- a/libc/src/string/memory_utils/op_generic.h
+++ b/libc/src/string/memory_utils/op_generic.h
@@ -125,7 +125,7 @@ template <typename T> constexpr size_t array_size_v = array_size<T>::value;
template <typename T> T load(CPtr src) {
static_assert(is_element_type_v<T>);
if constexpr (is_scalar_v<T> || is_vector_v<T>) {
- return ::LIBC_NAMESPACE::load<T>(src);
+ return load_unaligned<T>(src);
} else if constexpr (is_array_v<T>) {
using value_type = typename T::value_type;
T value;
@@ -138,7 +138,7 @@ template <typename T> T load(CPtr src) {
template <typename T> void store(Ptr dst, T value) {
static_assert(is_element_type_v<T>);
if constexpr (is_scalar_v<T> || is_vector_v<T>) {
- ::LIBC_NAMESPACE::store<T>(dst, value);
+ store_unaligned<T>(dst, value);
} else if constexpr (is_array_v<T>) {
using value_type = typename T::value_type;
for (size_t i = 0; i < array_size_v<T>; ++i)
@@ -357,7 +357,7 @@ template <typename T> struct Memmove {
// Making the offset explicit hints the compiler to use relevant addressing mode
// consistently.
template <typename T> LIBC_INLINE T load(CPtr ptr, size_t offset) {
- return ::LIBC_NAMESPACE::load<T>(ptr + offset);
+ return load_unaligned<T>(ptr + offset);
}
// Same as above but also makes sure the loaded value is in big endian format.
diff --git a/libc/src/string/memory_utils/utils.h b/libc/src/string/memory_utils/utils.h
index 9824c4b058b3a..b1a4885cb8c1f 100644
--- a/libc/src/string/memory_utils/utils.h
+++ b/libc/src/string/memory_utils/utils.h
@@ -211,14 +211,14 @@ LIBC_INLINE MemcmpReturnType cmp_neq_uint64_t(uint64_t a, uint64_t b) {
// Loads bytes from memory (possibly unaligned) and materializes them as
// type.
-template <typename T> LIBC_INLINE T load(CPtr ptr) {
+template <typename T> LIBC_INLINE T load_unaligned(CPtr ptr) {
T out;
memcpy_inline<sizeof(T)>(&out, ptr);
return out;
}
// Stores a value of type T in memory (possibly unaligned).
-template <typename T> LIBC_INLINE void store(Ptr ptr, T value) {
+template <typename T> LIBC_INLINE void store_unaligned(Ptr ptr, T value) {
memcpy_inline<sizeof(T)>(ptr, &value);
}
@@ -234,7 +234,7 @@ template <typename ValueType, typename T, typename... TS>
LIBC_INLINE ValueType load_aligned(CPtr src) {
static_assert(sizeof(ValueType) >= (sizeof(T) + ... + sizeof(TS)));
static_assert(Endian::IS_LITTLE || Endian::IS_BIG, "Invalid endianness");
- const ValueType value = load<T>(assume_aligned<sizeof(T)>(src));
+ const ValueType value = load_unaligned<T>(assume_aligned<sizeof(T)>(src));
if constexpr (sizeof...(TS) > 0) {
const ValueType next = load_aligned<ValueType, TS...>(src + sizeof(T));
@@ -274,12 +274,12 @@ LIBC_INLINE void store_aligned(ValueType value, Ptr dst) {
static_assert(sizeof(ValueType) >= (sizeof(T) + ... + sizeof(TS)));
constexpr size_t SHIFT = sizeof(T) * 8;
if constexpr (Endian::IS_LITTLE) {
- store<T>(assume_aligned<sizeof(T)>(dst), T(value & T(~0)));
+ store_unaligned<T>(assume_aligned<sizeof(T)>(dst), T(value & T(~0)));
if constexpr (sizeof...(TS) > 0)
store_aligned<ValueType, TS...>(value >> SHIFT, dst + sizeof(T));
} else if constexpr (Endian::IS_BIG) {
constexpr size_t OFFSET = (0 + ... + sizeof(TS));
- store<T>(assume_aligned<sizeof(T)>(dst + OFFSET), value & ~T(0));
+ store_unaligned<T>(assume_aligned<sizeof(T)>(dst + OFFSET), value & ~T(0));
if constexpr (sizeof...(TS) > 0)
store_aligned<ValueType, TS...>(value >> SHIFT, dst);
} else {
More information about the libc-commits
mailing list