diff options
author | Chris Robinson <[email protected]> | 2023-05-24 11:56:56 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-05-24 11:56:56 -0700 |
commit | f3e9d066df50a6e77e8c15ea97b195a4b069f254 (patch) | |
tree | 1823b869dd881b1c46243ba3e653979d210caba6 | |
parent | da56dd074595d6590273eeb1739f1c9bfc1b5fee (diff) |
Be a bit more safe with type mangling
-rw-r--r-- | al/event.cpp | 4 | ||||
-rw-r--r-- | alc/alu.cpp | 6 | ||||
-rw-r--r-- | common/albit.h | 7 | ||||
-rw-r--r-- | core/async_event.h | 8 | ||||
-rw-r--r-- | core/context.cpp | 6 | ||||
-rw-r--r-- | core/voice.cpp | 6 |
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); |