[libcxx-commits] [libcxx] [libc++] Fix shared_ptr<T[]>(Y*) rollback to use delete[] when allocation fails (PR #235691)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 28 19:05:53 PDT 2026


================
@@ -300,7 +300,11 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
                               ,
                           int> = 0>
   _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
+#if _LIBCPP_STD_VER >= 17
+    unique_ptr<_If<is_array_v<_Tp>, _Yp[], _Yp>> __hold(__p);
----------------
frederick-vs-ja wrote:

> I think I'd rather do that. This sounds to me like a defect and not intended behaviour. Can we check what other implementations do?

There're eventually 2 papers for related changes in (published) C++17 - [P0414R2](https://wg21.link/p0414r2) and [P0497R0](https://wg21.link/p0497r0).
- MSVC STL backports all these changes to C++14 mode.
- libc++ backports most but not all of them.
  - Removal of `operator*` & `operator->()` from `shared_ptr<T[]>`/`shared_ptr<T[N]>`, and
  - `reinterpret_pointer_cast`
are not backported.

I'm not sure whether changes to `element_type`, operators, and interaction with `enable_shared_from_this` should be backported. In the scope of this PR, I think it's fine to only backport the change of use of delete-expression.

----

@tomaszlewandowskivalidas I still think that it would be cleaner to introduce this helper template (to the namespace scope).

```C++
template <class _Tp, class _Yp>
struct __copy_arrayness_to {
  using type _LIBCPP_NODEBUG = _Yp;
};
template <class _Tp, class _Yp>
struct __copy_arrayness_to<_Tp[], _Yp> {
  using type _LIBCPP_NODEBUG = _Yp[];
};
template <class _Tp, size_t _Count, class _Yp>
struct __copy_arrayness_to<_Tp[_Count], _Yp> {
  using type _LIBCPP_NODEBUG = _Yp[];
};
```

And then unconditionally use `unique_ptr<typename __copy_arrayness_to<_Tp, _Yp>::type>` (instead of original `unique_ptr<_Yp>`) in the constructor.

Then we should test the change in all modes (although we possibly need to add `// XFAIL: FROZEN-CXX03-HEADERS-FIXME`).

----

On some test failure, it seems that some platforms don't have C++14 sized deallocation ([N3778](https://wg21.link/n3778)) enabled. Can we avoid reliance on `operator operator delete[](void*, size_t)`?

https://github.com/llvm/llvm-project/pull/235691


More information about the libcxx-commits mailing list