Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp @@ -20,14 +20,41 @@ #include "test_macros.h" +template> +struct has_less + : std::false_type +{}; + +template +struct has_less() < std::declval())>> + : std::true_type +{}; + struct A; // purposefully incomplete +struct B { int x = 42; }; -int main(int, char**) +template +void test() { - static_assert((std::is_same::element_type, A>::value), ""); + static_assert(std::is_same::element_type, T>::value); #if TEST_STD_VER > 14 - static_assert((std::is_same::weak_type, std::weak_ptr>::value), ""); + static_assert(std::is_same::weak_type, std::weak_ptr>::value); + static_assert(std::is_copy_constructible>::value); + static_assert(std::is_copy_assignable>::value); + static_assert(has_less>::value); +#if _LIBCPP_NEW_SHARED_PTR + static_assert(std::is_same ::element_type, T>::value); + static_assert(std::is_same::element_type, T>::value); +#endif #endif +} + +int main(int, char**) +{ + test(); + test(); + test(); + test(); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp @@ -13,11 +13,30 @@ #include #include +struct A { }; + +template +void test() +{ + { + std::shared_ptr p; + assert(p.use_count() == 0); + assert(p.get() == 0); + } + { + std::shared_ptr p {}; + assert(p.use_count() == 0); + assert(p.get() == 0); + } +} + int main(int, char**) { - std::shared_ptr p; - assert(p.use_count() == 0); - assert(p.get() == 0); + test(); + test(); + test(); +// test(); +// test(); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp @@ -27,21 +27,22 @@ int main(int, char**) { { - A* ptr = new A; - std::shared_ptr p(ptr); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); + A* ptr = new A; + std::shared_ptr p(ptr); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); } assert(A::count == 0); + { - A* ptr = new A; - std::shared_ptr p(ptr); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); + A* ptr = new A; + std::shared_ptr p(ptr); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); } assert(A::count == 0); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp @@ -30,16 +30,17 @@ int main(int, char**) { { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3)); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - test_deleter* d = std::get_deleter >(p); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); - assert(d); - assert(d->state() == 3); + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3)); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + + test_deleter* d = std::get_deleter>(p); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); + assert(d); + assert(d->state() == 3); } assert(A::count == 0); assert(test_deleter::count == 0); Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp @@ -27,22 +27,23 @@ int A::count = 0; - int main(int, char**) { + // TODO: add tests for whatever the result of 41930 happens to be. + { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3), test_allocator(5)); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - test_deleter* d = std::get_deleter >(p); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); - assert(d); - assert(d->state() == 3); - assert(test_allocator::count == 1); - assert(test_allocator::alloc_count == 1); + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3), test_allocator(5)); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + test_deleter* d = std::get_deleter >(p); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); + assert(d); + assert(d->state() == 3); + assert(test_allocator::count == 1); + assert(test_allocator::alloc_count == 1); } assert(A::count == 0); assert(test_deleter::count == 0); @@ -50,41 +51,41 @@ assert(test_allocator::count == 0); assert(test_allocator::alloc_count == 0); test_deleter::dealloc_count = 0; + // Test an allocator with a minimal interface { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3), bare_allocator()); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - test_deleter* d = std::get_deleter >(p); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); - assert(d); - assert(d->state() == 3); + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3), bare_allocator()); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + test_deleter* d = std::get_deleter >(p); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); + assert(d); + assert(d->state() == 3); } assert(A::count == 0); assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); test_deleter::dealloc_count = 0; -#if TEST_STD_VER >= 11 + // Test an allocator that returns class-type pointers { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3), min_allocator()); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - test_deleter* d = std::get_deleter >(p); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); - assert(d); - assert(d->state() == 3); + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3), min_allocator()); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + test_deleter* d = std::get_deleter >(p); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); + assert(d); + assert(d->state() == 3); } assert(A::count == 0); assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); -#endif - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp @@ -59,6 +59,7 @@ static_assert(( std::is_convertible, std::shared_ptr >::value), ""); static_assert((!std::is_convertible, std::shared_ptr >::value), ""); static_assert((!std::is_convertible, std::shared_ptr >::value), ""); + { std::shared_ptr pA(new A); assert(pA.use_count() == 1); @@ -69,27 +70,17 @@ std::shared_ptr pB(std::move(pA)); assert(B::count == 1); assert(A::count == 1); -#if TEST_STD_VER >= 11 assert(pB.use_count() == 1); assert(pA.use_count() == 0); -#else - assert(pB.use_count() == 2); - assert(pA.use_count() == 2); -#endif assert(p == pB.get()); } -#if TEST_STD_VER >= 11 assert(pA.use_count() == 0); assert(B::count == 0); assert(A::count == 0); -#else - assert(pA.use_count() == 1); - assert(B::count == 1); - assert(A::count == 1); -#endif } assert(B::count == 0); assert(A::count == 0); + { std::shared_ptr pA; assert(pA.use_count() == 0); @@ -102,6 +93,7 @@ assert(pB.use_count() == 0); assert(pA.use_count() == 0); assert(pA.get() == pB.get()); + assert(pA.get() == nullptr); } assert(pA.use_count() == 0); assert(B::count == 0); @@ -110,5 +102,5 @@ assert(B::count == 0); assert(A::count == 0); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_copy_move.fail.cpp =================================================================== --- /dev/null +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_copy_move.fail.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// shared_ptr + +// template shared_ptr(const shared_ptr& r); + +#include +#include + +struct A { int x = 42; }; + +struct ADel : std::default_delete +{ + typedef A* pointer; +}; + +int main(int, char**) +{ + static_assert(!std::is_convertible::value); + + { + std::shared_ptr pA; + std::shared_ptr pi(pA); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } + { + std::shared_ptr pA; + std::shared_ptr pi(std::move(pA)); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } + { + std::weak_ptr pA; + std::shared_ptr pi(std::move(pA)); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } + +#if TEST_STD_VER > 14 + { + std::unique_ptr ui; + std::shared_ptr pi(std::move(ui)); // expected-error {{no matching constructor for initialization of 'std::shared_ptr'}} + } +#endif + + return 0; +} Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp @@ -42,6 +42,7 @@ { std::shared_ptr pA(new A); assert(pA.use_count() == 1); + { B b; std::shared_ptr pB(pA, &b); @@ -58,5 +59,38 @@ assert(A::count == 0); assert(B::count == 0); - return 0; + { + std::shared_ptr p1(nullptr); + std::shared_ptr p2(p1, new int); + assert(p2.get() != nullptr); + } + { + std::shared_ptr p1(new int); + std::shared_ptr p2(p1, nullptr); + assert(p2.get() == nullptr); + } + +#if TEST_STD_VER > 14 + { + std::shared_ptr pA(new A); + assert(pA.use_count() == 1); + + { + B b; + std::shared_ptr pB(std::move(pA), &b); + assert(A::count == 1); + assert(B::count == 1); + assert(pA.use_count() == 2); + assert(pB.use_count() == 2); + assert(pB.get() == &b); + } + assert(pA.use_count() == 1); + assert(A::count == 1); + assert(B::count == 0); + } + assert(A::count == 0); + assert(B::count == 0); +#endif + + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp @@ -6,7 +6,8 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: sanitizer-new-delete +// UNSUPPORTED: sanitizer-new-delete, c++98, c++03 + // @@ -49,6 +50,20 @@ template void assert_deleter ( T * ) { assert(false); } +template +struct StatefulDeleter +{ + int state = 0; + + StatefulDeleter(int val = 0) : state(val) {} + StatefulDeleter(StatefulDeleter const&) { assert(false); } + + void operator()(T* ptr) { + assert(state == 42); + delete ptr; + } +}; + int main(int, char**) { { @@ -74,20 +89,31 @@ } catch (...) { -#if TEST_STD_VER >= 11 assert(A::count == 1); assert(B::count == 1); assert(ptr.get() == raw_ptr); -#else - (void) raw_ptr; // silence 'unused variable' warning - assert(A::count == 0); - assert(B::count == 0); - assert(ptr.get() == 0); -#endif } } #endif + +#if TEST_STD_VER > 14 + { + std::unique_ptr ptr; + std::shared_ptr p(std::move(ptr)); + assert(p.get() == 0); + assert(p.use_count() == 0); + } +#endif + + { + StatefulDeleter d; + std::unique_ptr&> u(new A, d); + std::shared_ptr p(std::move(u)); + d.state = 42; + assert(A::count == 1); + } assert(A::count == 0); + { // LWG 2399 fn(std::unique_ptr(new int)); } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp @@ -80,7 +80,7 @@ int i = 67; char c = 'e'; std::shared_ptr p = std::make_shared(i, c); - assert(globalMemCounter.checkOutstandingNewEq(nc+1)); + assert(globalMemCounter.checkOutstandingNewEq(nc+1)); // one for make_shared (create type ptr) and one for creation of control block. assert(A::count == 1); assert(p->get_int() == 67); assert(p->get_char() == 'e'); Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.private.fail.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.private.fail.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.private.fail.cpp @@ -26,5 +26,5 @@ { std::shared_ptr p = std::make_shared(); - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp @@ -24,7 +24,7 @@ int main(int, char**) { - std::shared_ptr p = std::make_shared(); // expected-error-re@memory:* {{static_assert failed{{.*}} "Can't construct object in make_shared"}} + std::shared_ptr p = std::make_shared(); // expected-error@memory:* {{static_assert failed due to requirement 'is_constructible::value' "Can't construct object in make_shared"}} return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.obs/op_bool.pass.cpp @@ -15,16 +15,32 @@ #include #include +struct A +{ + int a; + virtual ~A() {}; +}; +struct B : A { }; + int main(int, char**) { { - const std::shared_ptr p(new int(32)); - assert(p); + const std::shared_ptr p(new int(32)); + assert(p); + } + { + const std::shared_ptr p; + assert(!p); } { - const std::shared_ptr p; - assert(!p); + bool check = false; + std::shared_ptr basePtr = std::make_shared(); + + if (std::shared_ptr sp = std::dynamic_pointer_cast(basePtr)) + { check = true; } + + assert(check); } - return 0; + return 0; } Index: test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.assign/shared_ptr_Y.pass.cpp @@ -43,6 +43,7 @@ { { const std::shared_ptr pA(new A); + assert(pA.use_count() == 1); { std::weak_ptr pB; pB = pA; Index: test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp =================================================================== --- test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp +++ test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp @@ -105,5 +105,5 @@ assert(B::count == 0); assert(A::count == 0); - return 0; + return 0; }