[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.
This commit is contained in:
Triang3l 2024-05-12 17:23:40 +03:00
parent a90f83d44c
commit f0ad4f4587
1 changed files with 25 additions and 0 deletions

View File

@ -16,6 +16,7 @@
#include <functional> #include <functional>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <type_traits>
#include "xenia/base/assert.h" #include "xenia/base/assert.h"
#include "xenia/base/byte_order.h" #include "xenia/base/byte_order.h"
@ -24,6 +25,30 @@
namespace xe { namespace xe {
namespace memory { 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 <typename Dst, typename Src>
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<Dst>);
static_assert(std::is_trivially_copyable_v<Src>);
std::memcpy(&dst, &src, sizeof(Dst));
}
template <typename Dst, typename Src>
Dst Reinterpret(const Src& XE_RESTRICT_VAR src) {
Dst dst;
Reinterpret(dst, src);
return dst;
}
#if XE_PLATFORM_ANDROID #if XE_PLATFORM_ANDROID
void AndroidInitialize(); void AndroidInitialize();
void AndroidShutdown(); void AndroidShutdown();