From f3e9d066df50a6e77e8c15ea97b195a4b069f254 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 24 May 2023 11:56:56 -0700 Subject: Be a bit more safe with type mangling --- al/event.cpp | 4 ++-- alc/alu.cpp | 6 ++---- common/albit.h | 7 ++++--- core/async_event.h | 8 ++++++-- core/context.cpp | 6 ++++-- 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 _{context->mEventCbLock}; do { - auto *evt_ptr = reinterpret_cast(evt_data.buf); + auto *evt_ptr = std::launder(reinterpret_cast(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(reinterpret_cast(evt_data.buf)); + std::ignore = InitAsyncEvent(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( - reinterpret_cast(evt_vec.first.buf)); + auto &evt = InitAsyncEvent(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( - reinterpret_cast(evt_vec.first.buf)); + auto &evt = InitAsyncEvent(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 #include #include +#include #include #if !defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64)) #include @@ -16,9 +17,9 @@ std::enable_if_t, 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 dst; + std::memcpy(&dst, &src, sizeof(To)); + return *std::launder(reinterpret_cast(&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; template -auto &InitAsyncEvent(AsyncEvent *evt, Args&& ...args) -{ return std::get(*al::construct_at(evt, std::in_place_type, std::forward(args)...)); } +auto &InitAsyncEvent(std::byte *evtbuf, Args&& ...args) +{ + auto *evt = al::construct_at(reinterpret_cast(evtbuf), std::in_place_type, + std::forward(args)...); + return std::get(*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(evt_vec.first.buf), evt_vec.first.len); + std::destroy_n(std::launder(reinterpret_cast(evt_vec.first.buf)), + evt_vec.first.len); count += evt_vec.first.len; } if(evt_vec.second.len > 0) { - std::destroy_n(reinterpret_cast(evt_vec.second.buf), evt_vec.second.len); + std::destroy_n(std::launder(reinterpret_cast(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( - reinterpret_cast(evt_vec.first.buf)); + auto &evt = InitAsyncEvent(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( - reinterpret_cast(evt_vec.first.buf)); + auto &evt = InitAsyncEvent(evt_vec.first.buf); evt.mId = SourceID; evt.mCount = buffers_done; ring->writeAdvance(1); -- cgit v1.2.3