Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -3702,11 +3702,25 @@ _Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());} }; +template +void +__shared_ptr_emplace__destroy(_Tp& t) +{ + t.~_Tp(); +} + +template +void +__shared_ptr_emplace__destroy(_Tp (&t)[_N]) +{ + for (auto i = _N; i > 0; i--) __shared_ptr_emplace__destroy(t[i]); +} + template void __shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared() _NOEXCEPT { - __data_.second().~_Tp(); + __shared_ptr_emplace__destroy(__data_.second()); } template @@ -4340,7 +4354,8 @@ shared_ptr<_Tp> shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args) { - static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared" ); + // XXX is it okay to delete the line below? It seems like it is only checking if _Tp is an array. + // static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared" ); typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk; typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; typedef __allocator_destructor<_A2> _D2; @@ -4699,11 +4714,7 @@ template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - !is_array<_Tp>::value, - shared_ptr<_Tp> ->::type +shared_ptr<_Tp> make_shared(_Args&& ...__args) { return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...); Index: test/libcxx/memory/shared_ptr_array.pass.cpp =================================================================== --- test/libcxx/memory/shared_ptr_array.pass.cpp +++ test/libcxx/memory/shared_ptr_array.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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++98, c++03, c++11, c++14, c++17 + +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" +#include "test_allocator.h" + +template +void test_make_shared() +{ + std::shared_ptr foo = std::make_shared(); + std::shared_ptr bar(foo); + assert(typeid(**foo) == typeid(T) && "Type is not the same"); + assert(typeid(**bar) == typeid(T) && "Type is not the same"); +} + + +int main() +{ + test_make_shared(); + test_make_shared(); + test_make_shared(); +}