Skip to content

Commit b5cbb35

Browse files
ilya-biryukovtru
authored andcommitted
[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`. (cherry picked from commit f722db0)
1 parent e6de86c commit b5cbb35

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

libcxx/include/__memory/shared_ptr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,8 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
11341134
__alloc_.~_Alloc();
11351135
size_t __size = __unbounded_array_control_block::__bytes_for(__count_);
11361136
_AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
1137-
allocator_traits<_StorageAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*__storage), __size);
1137+
allocator_traits<_StorageAlloc>::deallocate(
1138+
__tmp, _PointerTraits::pointer_to(*__storage), __size / sizeof(_AlignedStorage));
11381139
}
11391140

11401141
_LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
@@ -1217,7 +1218,7 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc>
12171218

12181219
_ControlBlockAlloc __tmp(__alloc_);
12191220
__alloc_.~_Alloc();
1220-
allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), sizeof(*this));
1221+
allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), 1);
12211222
}
12221223

12231224
_LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
Lines changed: 27 additions & 0 deletions
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)