Closed
Description
The following snippet yields a new/delete type mismatch when building with sized deallocation:
int main(int argc, char *argv[]) {
std::allocate_shared<int64_t[]>(std::allocator<int64_t>{}, 1);
}
It runs fine with -stdlib=libc++ -fsanitize=address -std=c++20
, but fails when adding -fsized-deallocation
. Asan stack trace:
=================================================================
==1==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x504000000050 in thread T0:
object passed to delete has wrong type:
size of the allocated type: 40 bytes;
size of the deallocated type: 320 bytes.
#0 0x561aa17a18d2 in operator delete(void*, unsigned long) /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:164:3
#1 0x561aa17a4f6c in void std::__1::__libcpp_operator_delete[abi:v180000]<void*, unsigned long>(void*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:282:3
#2 0x561aa17a4f0c in void std::__1::__do_deallocate_handle_size[abi:v180000]<>(void*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:308:10
#3 0x561aa17a4eb4 in std::__1::__libcpp_deallocate[abi:v180000](void*, unsigned long, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:322:14
#4 0x561aa17a4e39 in std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>::deallocate[abi:v180000](std::__1::__sp_aligned_storage<8ul>*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator.h:130:13
#5 0x561aa17a4df4 in std::__1::allocator_traits<std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>>::deallocate[abi:v180000](std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>&, std::__1::__sp_aligned_storage<8ul>*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator_traits.h:288:13
#6 0x561aa17a4586 in std::__1::__unbounded_array_control_block<long [], std::__1::allocator<long>>::__on_zero_shared_weak() /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:1140:9
#7 0x561aa17a50ee in std::__1::__shared_weak_count::__release_shared[abi:v180000]() /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:215:9
#8 0x561aa17a31a5 in std::__1::shared_ptr<long []>::~shared_ptr[abi:v180000]() /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:775:23
#9 0x561aa17a305b in main /app/example.cpp:5:5
#10 0x7f028f312082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)
#11 0x561aa16c536d in _start (/app/output.s+0x2c36d)
0x504000000050 is located 0 bytes inside of 40-byte region [0x504000000050,0x504000000078)
allocated by thread T0 here:
#0 0x561aa17a0c6d in operator new(unsigned long) /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:95:3
#1 0x561aa17a3af4 in void* std::__1::__libcpp_operator_new[abi:v180000]<unsigned long>(unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:272:10
#2 0x561aa17a3a5c in std::__1::__libcpp_allocate[abi:v180000](unsigned long, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:298:10
#3 0x561aa17a399c in std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>::allocate[abi:v180000](unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator.h:114:38
#4 0x561aa17a392c in std::__1::allocator_traits<std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>>::allocate[abi:v180000](std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>&, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator_traits.h:268:20
#5 0x561aa17a3626 in std::__1::__allocation_guard<std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>>::__allocation_guard[abi:v180000]<std::__1::allocator<long>>(std::__1::allocator<long>, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocation_guard.h:57:18
#6 0x561aa17a3317 in std::__1::shared_ptr<long []> std::__1::__allocate_shared_unbounded_array[abi:v180000]<long [], std::__1::allocator<long>>(std::__1::allocator<long> const&, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:1162:39
#7 0x561aa17a30f7 in std::__1::shared_ptr<long []> std::__1::allocate_shared[abi:v180000]<long [], std::__1::allocator<long>, void>(std::__1::allocator<long> const&, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:1301:12
#8 0x561aa17a3052 in main /app/example.cpp:5:5
#9 0x7f028f312082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)
SUMMARY: AddressSanitizer: new-delete-type-mismatch /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:164:3 in operator delete(void*, unsigned long)
Live snippet: https://godbolt.org/z/ddYr6TYb1
Note: the mismatch was found by running the std::boyer_moore_searcher
example snippet on cppreference: https://godbolt.org/z/Gsx6dWPYn. Likely it has the same underlying issue, although this one does not require c++20 to reproduce.
The allocation divides by sizeof(_AlignedStorage)
, but the deallocation does not appear to make the same adjustment. That may be the source of the issue, which could be fixed w/ something like:
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -1137,7 +1137,9 @@
__alloc_.~_Alloc();
size_t __size = __unbounded_array_control_block::__bytes_for(__count_);
_AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
- allocator_traits<_StorageAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*__storage), __size);
+ allocator_traits<_StorageAlloc>::deallocate(
+ __tmp, _PointerTraits::pointer_to(*__storage),
+ __size / sizeof(_AlignedStorage));
}