aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-12-29 08:16:26 -0800
committerChris Robinson <[email protected]>2023-12-29 08:16:26 -0800
commita6942c271f1b27c79e274bdc87aa370b3bb81cc2 (patch)
treeeca41191a96f626768c07293efdb5ab195d93cb9
parent10ecdff7d1dfcc16bd2a090f089781310ea9a93d (diff)
Clean up some potential allocation alignment mismatches
-rw-r--r--common/almalloc.h37
-rw-r--r--common/pffft.cpp5
2 files changed, 19 insertions, 23 deletions
diff --git a/common/almalloc.h b/common/almalloc.h
index ac4ddfc2..b64b6b20 100644
--- a/common/almalloc.h
+++ b/common/almalloc.h
@@ -51,29 +51,23 @@ enum FamCount : size_t { };
\
gsl::owner<void*> operator new(size_t /*size*/, FamCount count) \
{ \
- const auto align = std::align_val_t(alignof(T)); \
- return ::new(align) std::byte[T::Sizeof(count)]; \
+ const auto alignment = std::align_val_t{alignof(T)}; \
+ return ::operator new[](T::Sizeof(count), alignment); \
} \
- void *operator new[](size_t /*size*/) = delete; \
void operator delete(gsl::owner<void*> block, FamCount) noexcept \
- { \
- const auto align = std::align_val_t(alignof(T)); \
- ::operator delete[](static_cast<gsl::owner<std::byte*>>(block), align); \
- } \
+ { ::operator delete[](block, std::align_val_t{alignof(T)}); } \
void operator delete(gsl::owner<void*> block) noexcept \
- { \
- const auto align = std::align_val_t(alignof(T)); \
- ::operator delete[](static_cast<gsl::owner<std::byte*>>(block), align); \
- } \
+ { ::operator delete[](block, std::align_val_t{alignof(T)}); } \
+ void *operator new[](size_t /*size*/) = delete; \
void operator delete[](void* /*block*/) = delete;
namespace al {
-template<typename T, std::size_t Align=alignof(T)>
+template<typename T, std::size_t AlignV=alignof(T)>
struct allocator {
- static constexpr auto alignment = std::max(Align, alignof(T));
- static constexpr auto AlignVal = std::align_val_t(alignment);
+ static constexpr auto Alignment = std::max(AlignV, alignof(T));
+ static constexpr auto AlignVal = std::align_val_t{Alignment};
using value_type = T;
using reference = T&;
@@ -86,25 +80,28 @@ struct allocator {
template<typename U>
struct rebind {
- using other = allocator<U, Align>;
+ using other = std::enable_if_t<alignof(U) <= Alignment, allocator<U,Alignment>>;
};
constexpr explicit allocator() noexcept = default;
template<typename U, std::size_t N>
- constexpr explicit allocator(const allocator<U,N>&) noexcept { }
+ constexpr explicit allocator(const allocator<U,N>&) noexcept
+ { static_assert(Alignment == allocator<U,N>::Alignment); }
gsl::owner<T*> allocate(std::size_t n)
{
if(n > std::numeric_limits<std::size_t>::max()/sizeof(T)) throw std::bad_alloc();
- return reinterpret_cast<gsl::owner<T*>>(::new(AlignVal) std::byte[n*sizeof(T)]);
+ return static_cast<gsl::owner<T*>>(::operator new[](n*sizeof(T), AlignVal));
}
void deallocate(gsl::owner<T*> p, std::size_t) noexcept
- { ::operator delete[](reinterpret_cast<gsl::owner<std::byte*>>(p), AlignVal); }
+ { ::operator delete[](gsl::owner<void*>{p}, AlignVal); }
};
template<typename T, std::size_t N, typename U, std::size_t M>
-constexpr bool operator==(const allocator<T,N>&, const allocator<U,M>&) noexcept { return true; }
+constexpr bool operator==(const allocator<T,N>&, const allocator<U,M>&) noexcept
+{ return allocator<T,N>::Alignment == allocator<U,M>::Alignment; }
template<typename T, std::size_t N, typename U, std::size_t M>
-constexpr bool operator!=(const allocator<T,N>&, const allocator<U,M>&) noexcept { return false; }
+constexpr bool operator!=(const allocator<T,N>&, const allocator<U,M>&) noexcept
+{ return allocator<T,N>::Alignment != allocator<U,M>::Alignment; }
template<typename T>
diff --git a/common/pffft.cpp b/common/pffft.cpp
index bbfbaa49..38380261 100644
--- a/common/pffft.cpp
+++ b/common/pffft.cpp
@@ -1438,7 +1438,7 @@ gsl::owner<PFFFT_Setup*> pffft_new_setup(unsigned int N, pffft_transform_t trans
const size_t storelen{std::max(offsetof(PFFFT_Setup, end) + 2_zu*Ncvec*sizeof(v4sf),
sizeof(PFFFT_Setup))};
- gsl::owner<std::byte*> storage{::new(V4sfAlignVal) std::byte[storelen]{}};
+ auto storage = static_cast<gsl::owner<std::byte*>>(::operator new[](storelen, V4sfAlignVal));
al::span extrastore{&storage[offsetof(PFFFT_Setup, end)], 2_zu*Ncvec*sizeof(v4sf)};
gsl::owner<PFFFT_Setup*> s{::new(storage) PFFFT_Setup{}};
@@ -1489,8 +1489,7 @@ gsl::owner<PFFFT_Setup*> pffft_new_setup(unsigned int N, pffft_transform_t trans
void pffft_destroy_setup(gsl::owner<PFFFT_Setup*> s) noexcept
{
std::destroy_at(s);
- auto storage = reinterpret_cast<gsl::owner<std::byte*>>(s);
- ::operator delete[](storage, V4sfAlignVal);
+ ::operator delete[](gsl::owner<void*>{s}, V4sfAlignVal);
}
#if !defined(PFFFT_SIMD_DISABLE)