From f0ad4f458735e8f843cc4f058c8cfec9206f4f0f Mon Sep 17 00:00:00 2001 From: Triang3l Date: Sun, 12 May 2024 17:23:40 +0300 Subject: [PATCH] [Base] Add aliasing-safe xe::memory::Reinterpret Accessing the same memory as different types (other than char) using reinterpret_cast or a union is undefined behavior that has already caused issues like #1971. Also adds a XE_RESTRICT_VAR definition for declaring non-aliasing pointers in performance-critical areas in the future. --- src/xenia/base/memory.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/xenia/base/memory.h b/src/xenia/base/memory.h index 14fb65968..3ed4dc3ab 100644 --- a/src/xenia/base/memory.h +++ b/src/xenia/base/memory.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "xenia/base/assert.h" #include "xenia/base/byte_order.h" @@ -24,6 +25,30 @@ namespace xe { namespace memory { +// For variable declarations (not return values or `this` pointer). +// Not propagated. +#define XE_RESTRICT_VAR __restrict + +// Aliasing-safe bit reinterpretation. +// For more complex cases such as non-trivially-copyable types, write copying +// code respecting the requirements for them externally instead of using these +// functions. + +template +void Reinterpret(Dst& XE_RESTRICT_VAR dst, const Src& XE_RESTRICT_VAR src) { + static_assert(sizeof(Dst) == sizeof(Src)); + static_assert(std::is_trivially_copyable_v); + static_assert(std::is_trivially_copyable_v); + std::memcpy(&dst, &src, sizeof(Dst)); +} + +template +Dst Reinterpret(const Src& XE_RESTRICT_VAR src) { + Dst dst; + Reinterpret(dst, src); + return dst; +} + #if XE_PLATFORM_ANDROID void AndroidInitialize(); void AndroidShutdown();