aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-05-24 11:56:56 -0700
committerChris Robinson <[email protected]>2023-05-24 11:56:56 -0700
commitf3e9d066df50a6e77e8c15ea97b195a4b069f254 (patch)
tree1823b869dd881b1c46243ba3e653979d210caba6
parentda56dd074595d6590273eeb1739f1c9bfc1b5fee (diff)
Be a bit more safe with type mangling
-rw-r--r--al/event.cpp4
-rw-r--r--alc/alu.cpp6
-rw-r--r--common/albit.h7
-rw-r--r--core/async_event.h8
-rw-r--r--core/context.cpp6
-rw-r--r--core/voice.cpp6
6 files changed, 20 insertions, 17 deletions
diff --git a/al/event.cpp b/al/event.cpp
index 7bd5ae1b..a5b5fdc5 100644
--- a/al/event.cpp
+++ b/al/event.cpp
@@ -56,7 +56,7 @@ int EventThread(ALCcontext *context)
std::lock_guard<std::mutex> _{context->mEventCbLock};
do {
- auto *evt_ptr = reinterpret_cast<AsyncEvent*>(evt_data.buf);
+ auto *evt_ptr = std::launder(reinterpret_cast<AsyncEvent*>(evt_data.buf));
evt_data.buf += sizeof(AsyncEvent);
evt_data.len -= 1;
@@ -164,7 +164,7 @@ void StopEventThrd(ALCcontext *ctx)
evt_data = ring->getWriteVector().first;
} while(evt_data.len == 0);
}
- std::ignore = InitAsyncEvent<AsyncKillThread>(reinterpret_cast<AsyncEvent*>(evt_data.buf));
+ std::ignore = InitAsyncEvent<AsyncKillThread>(evt_data.buf);
ring->writeAdvance(1);
ctx->mEventSem.post();
diff --git a/alc/alu.cpp b/alc/alu.cpp
index cf250988..c43da639 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -491,8 +491,7 @@ bool CalcEffectSlotParams(EffectSlot *slot, EffectSlot **sorted_slots, ContextBa
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len > 0) LIKELY
{
- AsyncEffectReleaseEvent &evt = InitAsyncEvent<AsyncEffectReleaseEvent>(
- reinterpret_cast<AsyncEvent*>(evt_vec.first.buf));
+ auto &evt = InitAsyncEvent<AsyncEffectReleaseEvent>(evt_vec.first.buf);
evt.mEffectState = oldstate;
ring->writeAdvance(1);
}
@@ -1701,8 +1700,7 @@ void SendSourceStateEvent(ContextBase *context, uint id, VChangeState state)
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len < 1) return;
- AsyncSourceStateEvent &evt = InitAsyncEvent<AsyncSourceStateEvent>(
- reinterpret_cast<AsyncEvent*>(evt_vec.first.buf));
+ auto &evt = InitAsyncEvent<AsyncSourceStateEvent>(evt_vec.first.buf);
evt.mId = id;
switch(state)
{
diff --git a/common/albit.h b/common/albit.h
index a563a4e7..962eb0aa 100644
--- a/common/albit.h
+++ b/common/albit.h
@@ -4,6 +4,7 @@
#include <cstdint>
#include <cstring>
#include <limits>
+#include <new>
#include <type_traits>
#if !defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64))
#include <intrin.h>
@@ -16,9 +17,9 @@ std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From
&& std::is_trivially_copyable_v<To>,
To> bit_cast(const From &src) noexcept
{
- union { char c; To dst; } u;
- std::memcpy(&u.dst, &src, sizeof(To));
- return u.dst;
+ std::aligned_storage_t<sizeof(To), alignof(To)> dst;
+ std::memcpy(&dst, &src, sizeof(To));
+ return *std::launder(reinterpret_cast<To*>(&dst));
}
#ifdef __BYTE_ORDER__
diff --git a/core/async_event.h b/core/async_event.h
index 9e2d1193..c049fa02 100644
--- a/core/async_event.h
+++ b/core/async_event.h
@@ -54,7 +54,11 @@ using AsyncEvent = std::variant<AsyncKillThread,
AsyncDisconnectEvent>;
template<typename T, typename ...Args>
-auto &InitAsyncEvent(AsyncEvent *evt, Args&& ...args)
-{ return std::get<T>(*al::construct_at(evt, std::in_place_type<T>, std::forward<Args>(args)...)); }
+auto &InitAsyncEvent(std::byte *evtbuf, Args&& ...args)
+{
+ auto *evt = al::construct_at(reinterpret_cast<AsyncEvent*>(evtbuf), std::in_place_type<T>,
+ std::forward<Args>(args)...);
+ return std::get<T>(*evt);
+}
#endif
diff --git a/core/context.cpp b/core/context.cpp
index 145ce349..2ebbc7b1 100644
--- a/core/context.cpp
+++ b/core/context.cpp
@@ -66,12 +66,14 @@ ContextBase::~ContextBase()
auto evt_vec = mAsyncEvents->getReadVector();
if(evt_vec.first.len > 0)
{
- std::destroy_n(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf), evt_vec.first.len);
+ std::destroy_n(std::launder(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf)),
+ evt_vec.first.len);
count += evt_vec.first.len;
}
if(evt_vec.second.len > 0)
{
- std::destroy_n(reinterpret_cast<AsyncEvent*>(evt_vec.second.buf), evt_vec.second.len);
+ std::destroy_n(std::launder(reinterpret_cast<AsyncEvent*>(evt_vec.second.buf)),
+ evt_vec.second.len);
count += evt_vec.second.len;
}
if(count > 0)
diff --git a/core/voice.cpp b/core/voice.cpp
index 3e78b176..65986cd1 100644
--- a/core/voice.cpp
+++ b/core/voice.cpp
@@ -226,8 +226,7 @@ void SendSourceStoppedEvent(ContextBase *context, uint id)
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len < 1) return;
- AsyncSourceStateEvent &evt = InitAsyncEvent<AsyncSourceStateEvent>(
- reinterpret_cast<AsyncEvent*>(evt_vec.first.buf));
+ auto &evt = InitAsyncEvent<AsyncSourceStateEvent>(evt_vec.first.buf);
evt.mId = id;
evt.mState = AsyncSrcState::Stop;
@@ -1151,8 +1150,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len > 0)
{
- AsyncBufferCompleteEvent &evt = InitAsyncEvent<AsyncBufferCompleteEvent>(
- reinterpret_cast<AsyncEvent*>(evt_vec.first.buf));
+ auto &evt = InitAsyncEvent<AsyncBufferCompleteEvent>(evt_vec.first.buf);
evt.mId = SourceID;
evt.mCount = buffers_done;
ring->writeAdvance(1);