From 8f1354b98541354c86b4b3289ef641ae16f8c2b1 Mon Sep 17 00:00:00 2001 From: no92 Date: Mon, 18 Mar 2024 20:25:05 +0100 Subject: [PATCH] options/internal: fix UB in PhD mem{cpy,set} --- options/internal/generic/essential.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/options/internal/generic/essential.cpp b/options/internal/generic/essential.cpp index d00df1e002..3c4f64e85b 100644 --- a/options/internal/generic/essential.cpp +++ b/options/internal/generic/essential.cpp @@ -5,8 +5,7 @@ namespace { // Needed since we cannot declare a templated enum. template struct word_helper { - using underlying [[gnu::aligned(1)]] = T; - enum class [[gnu::may_alias]] word_enum : underlying { }; + enum class [[gnu::may_alias, gnu::aligned(1)]] word_enum : T { }; }; template @@ -15,7 +14,8 @@ namespace { template [[gnu::always_inline]] inline word alias_load(const unsigned char *&p) { - word value = *reinterpret_cast *>(p); + word value; + __builtin_memcpy(&value, p, sizeof(value)); p += sizeof(T); return value; } @@ -23,15 +23,18 @@ namespace { template [[gnu::always_inline]] inline void alias_store(unsigned char *&p, word value) { - *reinterpret_cast *>(p) = value; + __builtin_memcpy(p, &value, sizeof(value)); p += sizeof(T); } -#ifdef __LP64__ +#if defined(__LP64__) && !defined(__riscv) void *forward_copy(void *__restrict dest, const void *__restrict src, size_t n) { auto curDest = reinterpret_cast(dest); auto curSrc = reinterpret_cast(src); + for(; uintptr_t(curSrc) % 4 && n; n--) + *curDest++ = *curSrc++; + while(n >= 8 * 8) { auto w1 = alias_load(curSrc); auto w2 = alias_load(curSrc); @@ -118,7 +121,7 @@ void *memset(void *dest, int val, size_t n) { unsigned char byte = val; // Get rid of misalignment. - while(n && (reinterpret_cast(curDest) & 7)) { + while(n && (uintptr_t(curDest) & 7)) { *curDest++ = byte; --n; }