From 0d4f2ff9140fe08b89dcf473ace38ad3d709a1b1 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 18 May 2022 01:14:43 +0300 Subject: [PATCH] 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 (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::StringMapEntry::Create(llvm::StringRef, llvm::MallocAllocator&, llvm::cl::Option*&&) () 7 0x000000002b9e9428 in std::__1::pair, bool> llvm::StringMap::try_emplace(llvm::StringRef, llvm::cl::Option*&&) () 8 0x000000002b9e925f in llvm::StringMap::insert(std::__1::pair) () 9 0x000000002b9dc689 in (anonymous namespace)::CommandLineParser::addOption(llvm::cl::Option*, llvm::cl::SubCommand*) () 10 0x000000002b9cf219 in (anonymous namespace)::CommandLineParser::addOption(llvm::cl::Option*, bool) () 11 0x000000002b9ce831 in llvm::cl::Option::addArgument() () --- src/alloc-posix.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/alloc-posix.c b/src/alloc-posix.c index 176e7ec3..43130c9a 100644 --- a/src/alloc-posix.c +++ b/src/alloc-posix.c @@ -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 + // C11 requires alignment>0 && integral multiple, see + // 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