Skip to content

Commit

Permalink
[libc++] Use correct size for deallocation of arrays in shared_ptr (#…
Browse files Browse the repository at this point in the history
…68233)

Fixes #68051.

Current implementation passes the number of `_AlignedStorage` objects
when it calls to `allocate` and the number of **bytes** on `deallocate`.
This only applies to allocations that allocate control block and the
storage together, i.e. `make_shared` and `allocate_shared`.

Found by ASan under Clang combined with `-fsized-deallocation`.

(cherry picked from commit f722db02d359e29ca001b78197ee1a275f8c3d7c)
  • Loading branch information
ilya-biryukov authored and tru committed Nov 20, 2023
1 parent e6de86c commit b5cbb35
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
5 changes: 3 additions & 2 deletions libcxx/include/__memory/shared_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,8 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
__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));
}

_LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
Expand Down Expand Up @@ -1217,7 +1218,7 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>

_ControlBlockAlloc __tmp(__alloc_);
__alloc_.~_Alloc();
allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), sizeof(*this));
allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), 1);
}

_LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
Expand Down
27 changes: 27 additions & 0 deletions libcxx/test/libcxx/memory/shared_ptr_array.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// REQUIRES: -fsized-deallocation
// ADDITIONAL_COMPILE_FLAGS: -fsized-deallocation

// This test will fail with ASan if the implementation passes different sizes
// to corresponding allocation and deallocation functions.

#include <memory>

int main(int, char**) {
std::allocate_shared<int[]>(std::allocator<int>{}, 10);
std::make_shared<int[]>(10);

std::allocate_shared<int[10]>(std::allocator<int>{});
std::make_shared<int[10]>();

return 0;
}

0 comments on commit b5cbb35

Please sign in to comment.