Skip to content

Commit

Permalink
options/internal: fix UB in PhD mem{cpy,set}
Browse files Browse the repository at this point in the history
  • Loading branch information
no92 committed Mar 18, 2024
1 parent 827824a commit 8f1354b
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions options/internal/generic/essential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ namespace {
// Needed since we cannot declare a templated enum.
template<typename T>
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<typename T>
Expand All @@ -15,23 +14,27 @@ namespace {
template<typename T>
[[gnu::always_inline]]
inline word<T> alias_load(const unsigned char *&p) {
word<T> value = *reinterpret_cast<const word<T> *>(p);
word<T> value;
__builtin_memcpy(&value, p, sizeof(value));
p += sizeof(T);
return value;
}

template<typename T>
[[gnu::always_inline]]
inline void alias_store(unsigned char *&p, word<T> value) {
*reinterpret_cast<word<T> *>(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<unsigned char *>(dest);
auto curSrc = reinterpret_cast<const unsigned char *>(src);

for(; uintptr_t(curSrc) % 4 && n; n--)
*curDest++ = *curSrc++;

while(n >= 8 * 8) {
auto w1 = alias_load<uint64_t>(curSrc);
auto w2 = alias_load<uint64_t>(curSrc);
Expand Down Expand Up @@ -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<uintptr_t>(curDest) & 7)) {
while(n && (uintptr_t(curDest) & 7)) {
*curDest++ = byte;
--n;
}
Expand Down

0 comments on commit 8f1354b

Please sign in to comment.