1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// UNSUPPORTED: sanitizer-new-delete
11
12// <memory>
13
14// template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);
15
16#include <memory>
17#include <new>
18#include <cstdlib>
19#include <cassert>
20
21#include "test_macros.h"
22#include "count_new.hpp"
23
24struct B
25{
26    static int count;
27
28    B() {++count;}
29    B(const B&) {++count;}
30    virtual ~B() {--count;}
31};
32
33int B::count = 0;
34
35struct A
36    : public B
37{
38    static int count;
39
40    A() {++count;}
41    A(const A&) {++count;}
42    ~A() {--count;}
43};
44
45int A::count = 0;
46
47void fn ( const std::shared_ptr<int> &) {}
48void fn ( const std::shared_ptr<B> &) { assert (false); }
49
50template <typename T>
51void assert_deleter ( T * ) { assert(false); }
52
53int main()
54{
55    {
56        std::unique_ptr<A> ptr(new A);
57        A* raw_ptr = ptr.get();
58        std::shared_ptr<B> p(std::move(ptr));
59        assert(A::count == 1);
60        assert(B::count == 1);
61        assert(p.use_count() == 1);
62        assert(p.get() == raw_ptr);
63        assert(ptr.get() == 0);
64    }
65#ifndef TEST_HAS_NO_EXCEPTIONS
66    assert(A::count == 0);
67    {
68        std::unique_ptr<A> ptr(new A);
69        A* raw_ptr = ptr.get();
70        globalMemCounter.throw_after = 0;
71        try
72        {
73            std::shared_ptr<B> p(std::move(ptr));
74            assert(false);
75        }
76        catch (...)
77        {
78#if TEST_STD_VER >= 11
79            assert(A::count == 1);
80            assert(B::count == 1);
81            assert(ptr.get() == raw_ptr);
82#else
83            assert(A::count == 0);
84            assert(B::count == 0);
85            assert(ptr.get() == 0);
86#endif
87        }
88    }
89#endif
90    assert(A::count == 0);
91    { // LWG 2399
92        fn(std::unique_ptr<int>(new int));
93    }
94#if TEST_STD_VER >= 14
95    { // LWG 2415
96        std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>);
97        std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope
98    }
99#endif
100}
101