From 51ff09dc1ef1777dbe0421b6281ad10f98d61c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:24:46 +0200 Subject: [PATCH] Fix memory alignment on 32-bit Windows. --- core/os/memory.h | 13 +++++++++++-- core/templates/cowdata.h | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/os/memory.h b/core/os/memory.h index 2491d64ea48..f7d9d5c1687 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -41,7 +41,16 @@ constexpr size_t get_aligned_address(size_t p_address, size_t p_alignment) { return (n_bytes_unaligned == 0) ? p_address : (p_address + p_alignment - n_bytes_unaligned); } -// Alignment: ↓ max_align_t ↓ uint64_t ↓ max_align_t +#if defined(__MINGW32__) && !defined(__MINGW64__) +// Note: Using hardcoded value, since the value can end up different in different compile units on 32-bit windows +// due to a compiler bug (see GH-113145) +static constexpr size_t MAX_ALIGN = 16; +static_assert(MAX_ALIGN % alignof(max_align_t) == 0); +#else +static constexpr size_t MAX_ALIGN = alignof(max_align_t); +#endif + +// Alignment: ↓ max_align_t ↓ uint64_t ↓ MAX_ALIGN // ┌─────────────────┬──┬────────────────┬──┬───────────... // │ uint64_t │░░│ uint64_t │░░│ T[] // │ alloc size │░░│ element count │░░│ data @@ -50,7 +59,7 @@ constexpr size_t get_aligned_address(size_t p_address, size_t p_alignment) { inline constexpr size_t SIZE_OFFSET = 0; inline constexpr size_t ELEMENT_OFFSET = get_aligned_address(SIZE_OFFSET + sizeof(uint64_t), alignof(uint64_t)); -inline constexpr size_t DATA_OFFSET = get_aligned_address(ELEMENT_OFFSET + sizeof(uint64_t), alignof(max_align_t)); +inline constexpr size_t DATA_OFFSET = get_aligned_address(ELEMENT_OFFSET + sizeof(uint64_t), MAX_ALIGN); template void *alloc_static(size_t p_bytes, bool p_pad_align = false); diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index 359a6fe269b..9be5aa32f8e 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -60,7 +60,7 @@ public: static constexpr USize MAX_INT = INT64_MAX; private: - // Alignment: ↓ max_align_t ↓ USize ↓ USize ↓ max_align_t + // Alignment: ↓ max_align_t ↓ USize ↓ USize ↓ MAX_ALIGN // ┌────────────────────┬──┬───────────────┬──┬─────────────┬──┬───────────... // │ SafeNumeric │░░│ USize │░░│ USize │░░│ T[] // │ ref. count │░░│ data capacity │░░│ data size │░░│ data @@ -70,7 +70,7 @@ private: static constexpr size_t REF_COUNT_OFFSET = 0; static constexpr size_t CAPACITY_OFFSET = Memory::get_aligned_address(REF_COUNT_OFFSET + sizeof(SafeNumeric), alignof(USize)); static constexpr size_t SIZE_OFFSET = Memory::get_aligned_address(CAPACITY_OFFSET + sizeof(USize), alignof(USize)); - static constexpr size_t DATA_OFFSET = Memory::get_aligned_address(SIZE_OFFSET + sizeof(USize), alignof(max_align_t)); + static constexpr size_t DATA_OFFSET = Memory::get_aligned_address(SIZE_OFFSET + sizeof(USize), Memory::MAX_ALIGN); mutable T *_ptr = nullptr;