Description
This makes the attached program crash (…in most runs, not 100% of the time):
% out/gn/bin/clang++ unique.cc -isysroot $(xcrun -show-sdk-path) -std=c++20 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE % ./a.out zsh: trace trap ./a.out
lldb shows that this indeed this check:
frame #0: 0x00000001000029e4 a.out`std::__1::unique_ptr<std::__1::vector<int, std::__1::allocator<int>> [], AlignedDeleter<std::__1::vector<int, std::__1::allocator<int>>>>::operator[][abi:se200000](unsigned long) const [inlined] __clang_trap_msg$libc++$/Users/thakis/src/llvm-project/out/gn/bin/../include/c++/v1/__memory/unique_ptr.h:566: assertion __checker_.__in_bounds(std::__to_address(__ptr_), __i) failed: unique_ptr<T[]>::operator[](index): index out of range
The program uses a unique_ptr with a custom deleter to refer to raw malloc-ed memory, "to allow having uninitialized entries inside it".
It has this typedef:
template <typename T> using AlignedUniquePtr = std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;
It uses this typedef with an array type:
// Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]> // to allow having uninitialized entries inside it. AlignedUniquePtr<T[]> entries_;
It creates objects of this unique_ptr like so:
template <typename T> AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) { using TU = typename std::remove_extent<T>::type; return AlignedUniquePtr<T>( static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs))); }
AlignedAlloc()
is basically malloc – in particular, nothing callsnew[]
, so it doesn't write an array cookie.The custom deleter looks like so (
AlignedFree()
is justfree()
):template <typename T> struct AlignedDeleter { inline void operator()(T* ptr) const { AlignedFree(ptr); } };
The class containing
entries_
calls dtors as needed, and the deleter really only needs to free memory.delete []
is never called.Is this a valid use of unique_ptr<T[]>? If so, should this hardening only be used for unique_ptrs that don't have a custom deleter?
Originally posted by @nico in #91798 (comment)