Skip to content

Commit f722db0

Browse files
[libc++] Use correct size for deallocation of arrays in shared_ptr (#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`.
1 parent e22818d commit f722db0

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

libcxx/include/__memory/shared_ptr.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,8 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
11371137
__alloc_.~_Alloc();
11381138
size_t __size = __unbounded_array_control_block::__bytes_for(__count_);
11391139
_AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
1140-
allocator_traits<_StorageAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*__storage), __size);
1140+
allocator_traits<_StorageAlloc>::deallocate(
1141+
__tmp, _PointerTraits::pointer_to(*__storage), __size / sizeof(_AlignedStorage));
11411142
}
11421143

11431144
_LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
@@ -1220,7 +1221,7 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>
12201221

12211222
_ControlBlockAlloc __tmp(__alloc_);
12221223
__alloc_.~_Alloc();
1223-
allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), sizeof(*this));
1224+
allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), 1);
12241225
}
12251226

12261227
_LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
10+
// UNSUPPORTED: c++03, c++11, c++14, c++17
11+
// REQUIRES: -fsized-deallocation
12+
// ADDITIONAL_COMPILE_FLAGS: -fsized-deallocation
13+
14+
// This test will fail with ASan if the implementation passes different sizes
15+
// to corresponding allocation and deallocation functions.
16+
17+
#include <memory>
18+
19+
int main(int, char**) {
20+
std::allocate_shared<int[]>(std::allocator<int>{}, 10);
21+
std::make_shared<int[]>(10);
22+
23+
std::allocate_shared<int[10]>(std::allocator<int>{});
24+
std::make_shared<int[10]>();
25+
26+
return 0;
27+
}

0 commit comments

Comments
 (0)