Skip to content

Commit f0ad4f4

Browse files
committed
[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.
1 parent a90f83d commit f0ad4f4

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/xenia/base/memory.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <functional>
1717
#include <string>
1818
#include <string_view>
19+
#include <type_traits>
1920

2021
#include "xenia/base/assert.h"
2122
#include "xenia/base/byte_order.h"
@@ -24,6 +25,30 @@
2425
namespace xe {
2526
namespace memory {
2627

28+
// For variable declarations (not return values or `this` pointer).
29+
// Not propagated.
30+
#define XE_RESTRICT_VAR __restrict
31+
32+
// Aliasing-safe bit reinterpretation.
33+
// For more complex cases such as non-trivially-copyable types, write copying
34+
// code respecting the requirements for them externally instead of using these
35+
// functions.
36+
37+
template <typename Dst, typename Src>
38+
void Reinterpret(Dst& XE_RESTRICT_VAR dst, const Src& XE_RESTRICT_VAR src) {
39+
static_assert(sizeof(Dst) == sizeof(Src));
40+
static_assert(std::is_trivially_copyable_v<Dst>);
41+
static_assert(std::is_trivially_copyable_v<Src>);
42+
std::memcpy(&dst, &src, sizeof(Dst));
43+
}
44+
45+
template <typename Dst, typename Src>
46+
Dst Reinterpret(const Src& XE_RESTRICT_VAR src) {
47+
Dst dst;
48+
Reinterpret(dst, src);
49+
return dst;
50+
}
51+
2752
#if XE_PLATFORM_ANDROID
2853
void AndroidInitialize();
2954
void AndroidShutdown();

0 commit comments

Comments
 (0)