Relax aligned_alloc() restrictions

"Passing a size which is not an integral multiple of alignment" is too
strict, and lots of code relies on it, i.e.:

    (gdb) bt
    0  mi_aligned_alloc (alignment=8, size=44) at alloc-posix.c:88
    1  0x000000002dc55fdd in aligned_alloc (alignment=8, size=44) at alloc-override.c:251
    2  0x0000000017be85b6 in Memory::newImpl<std::align_val_t> (size=44, align=(unknown: 8)) at memory.h:47
    3  operator new (size=44, align=(unknown: 8)) at new_delete.cpp:60
    4  0x000000002ba66c5d in llvm::allocate_buffer(unsigned long, unsigned long) ()
    5  0x000000002898eba1 in llvm::MallocAllocator::Allocate(unsigned long, unsigned long) ()
    6  0x000000002b9e95ee in llvm::StringMapEntry<llvm:🆑:Option*>* llvm::StringMapEntry<llvm:🆑:Option*>::Create<llvm::MallocAllocator, llvm:🆑:Option*>(llvm::StringRef, llvm::MallocAllocator&, llvm:🆑:Option*&&) ()
    7  0x000000002b9e9428 in std::__1::pair<llvm::StringMapIterator<llvm:🆑:Option*>, bool> llvm::StringMap<llvm:🆑:Option*, llvm::MallocAllocator>::try_emplace<llvm:🆑:Option*>(llvm::StringRef, llvm:🆑:Option*&&) ()
    8  0x000000002b9e925f in llvm::StringMap<llvm:🆑:Option*, llvm::MallocAllocator>::insert(std::__1::pair<llvm::StringRef, llvm:🆑:Option*>) ()
    9  0x000000002b9dc689 in (anonymous namespace)::CommandLineParser::addOption(llvm:🆑:Option*, llvm:🆑:SubCommand*) ()
    10 0x000000002b9cf219 in (anonymous namespace)::CommandLineParser::addOption(llvm:🆑:Option*, bool) ()
    11 0x000000002b9ce831 in llvm:🆑:Option::addArgument() ()
This commit is contained in:
Azat Khuzhin 2022-05-18 01:14:43 +03:00
parent f2712f4a8f
commit 0d4f2ff914

View file

@ -83,7 +83,10 @@ mi_decl_nodiscard mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcep
}
mi_decl_nodiscard mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept {
if (mi_unlikely((size&(alignment-1)) != 0)) { // C11 requires alignment>0 && integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc>
// C11 requires alignment>0 && integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc>
// but "Passing a size which is not an integral multiple of alignment" it is too strict,
// and lots of code relies on this.
if (mi_unlikely(alignment==0 || !_mi_is_power_of_two(alignment))) {
#if MI_DEBUG > 0
_mi_error_message(EOVERFLOW, "(mi_)aligned_alloc requires the size to be an integral multiple of the alignment (size %zu, alignment %zu)\n", size, alignment);
#endif