Skip to content

Commit fd37495

Browse files
authored
32-bit MinGW g++ doesn't call the correct overload for the new operator when a type is 16 bytes aligned. (jrouwe#1614)
It uses the non-aligned version, which on 32 bit platforms usually returns an 8 byte aligned block. We therefore default to 16 byte aligned allocations when the regular new operator is used. See: godotengine/godot#105455 (comment)
1 parent e73521b commit fd37495

2 files changed

Lines changed: 17 additions & 4 deletions

File tree

Docs/ReleaseNotes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ For breaking API changes see [this document](https://github.com/jrouwe/JoltPhysi
1111

1212
### Bug Fixes
1313

14+
* 32-bit MinGW g++ doesn't call the correct overload for the new operator when a type is 16 bytes aligned. This could cause unaligned read access violations.
1415
* Fixed compiling in double precision and fixed issues with floating point contraction that caused unit test failures on LoongArch architecture.
1516
* Added an epsilon to the `CastRay` / `CastShape` early out condition to avoid dividing by a very small number and overflowing to INF. This can cause a float overflow exception.
1617
* Fixed Samples requiring Vulkan extension `VK_EXT_device_address_binding_report` without checking if it is available.

Jolt/Core/Memory.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,24 @@ JPH_EXPORT extern AlignedFreeFunction AlignedFree;
2727
/// Register platform default allocation / free functions
2828
JPH_EXPORT void RegisterDefaultAllocator();
2929

30+
// 32-bit MinGW g++ doesn't call the correct overload for the new operator when a type is 16 bytes aligned.
31+
// It uses the non-aligned version, which on 32 bit platforms usually returns an 8 byte aligned block.
32+
// We therefore default to 16 byte aligned allocations when the regular new operator is used.
33+
// See: https://github.com/godotengine/godot/issues/105455#issuecomment-2824311547
34+
#if defined(JPH_COMPILER_MINGW) && JPH_CPU_ADDRESS_BITS == 32
35+
#define JPH_INTERNAL_DEFAULT_ALLOCATE(size) JPH::AlignedAllocate(size, 16)
36+
#define JPH_INTERNAL_DEFAULT_FREE(pointer) JPH::AlignedFree(pointer)
37+
#else
38+
#define JPH_INTERNAL_DEFAULT_ALLOCATE(size) JPH::Allocate(size)
39+
#define JPH_INTERNAL_DEFAULT_FREE(pointer) JPH::Free(pointer)
40+
#endif
41+
3042
/// Macro to override the new and delete functions
3143
#define JPH_OVERRIDE_NEW_DELETE \
32-
JPH_INLINE void *operator new (size_t inCount) { return JPH::Allocate(inCount); } \
33-
JPH_INLINE void operator delete (void *inPointer) noexcept { JPH::Free(inPointer); } \
34-
JPH_INLINE void *operator new[] (size_t inCount) { return JPH::Allocate(inCount); } \
35-
JPH_INLINE void operator delete[] (void *inPointer) noexcept { JPH::Free(inPointer); } \
44+
JPH_INLINE void *operator new (size_t inCount) { return JPH_INTERNAL_DEFAULT_ALLOCATE(inCount); } \
45+
JPH_INLINE void operator delete (void *inPointer) noexcept { JPH_INTERNAL_DEFAULT_FREE(inPointer); } \
46+
JPH_INLINE void *operator new[] (size_t inCount) { return JPH_INTERNAL_DEFAULT_ALLOCATE(inCount); } \
47+
JPH_INLINE void operator delete[] (void *inPointer) noexcept { JPH_INTERNAL_DEFAULT_FREE(inPointer); } \
3648
JPH_INLINE void *operator new (size_t inCount, std::align_val_t inAlignment) { return JPH::AlignedAllocate(inCount, static_cast<size_t>(inAlignment)); } \
3749
JPH_INLINE void operator delete (void *inPointer, [[maybe_unused]] std::align_val_t inAlignment) noexcept { JPH::AlignedFree(inPointer); } \
3850
JPH_INLINE void *operator new[] (size_t inCount, std::align_val_t inAlignment) { return JPH::AlignedAllocate(inCount, static_cast<size_t>(inAlignment)); } \

0 commit comments

Comments
 (0)