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 // <memory>
11 
12 // template<class Y> explicit shared_ptr(auto_ptr<Y>&& r);
13 
14 // UNSUPPORTED: sanitizer-new-delete
15 
16 #include <memory>
17 #include <new>
18 #include <cstdlib>
19 #include <cassert>
20 
21 bool throw_next = false;
22 
operator new(std::size_t s)23 void* operator new(std::size_t s) throw(std::bad_alloc)
24 {
25     if (throw_next)
26         throw std::bad_alloc();
27     return std::malloc(s);
28 }
29 
operator delete(void * p)30 void  operator delete(void* p) throw()
31 {
32     std::free(p);
33 }
34 
35 struct B
36 {
37     static int count;
38 
BB39     B() {++count;}
BB40     B(const B&) {++count;}
~BB41     virtual ~B() {--count;}
42 };
43 
44 int B::count = 0;
45 
46 struct A
47     : public B
48 {
49     static int count;
50 
AA51     A() {++count;}
AA52     A(const A&) {++count;}
~AA53     ~A() {--count;}
54 };
55 
56 int A::count = 0;
57 
main()58 int main()
59 {
60     {
61     std::auto_ptr<A> ptr(new A);
62     A* raw_ptr = ptr.get();
63 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
64     std::shared_ptr<B> p(std::move(ptr));
65 #else
66     std::shared_ptr<B> p(ptr);
67 #endif
68     assert(A::count == 1);
69     assert(B::count == 1);
70     assert(p.use_count() == 1);
71     assert(p.get() == raw_ptr);
72     assert(ptr.get() == 0);
73     }
74     assert(A::count == 0);
75     {
76     std::auto_ptr<A> ptr(new A);
77     A* raw_ptr = ptr.get();
78     throw_next = true;
79     try
80     {
81 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
82         std::shared_ptr<B> p(std::move(ptr));
83 #else
84         std::shared_ptr<B> p(ptr);
85 #endif
86         assert(false);
87     }
88     catch (...)
89     {
90 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
91         assert(A::count == 1);
92         assert(B::count == 1);
93         assert(ptr.get() == raw_ptr);
94 #else
95         // Without rvalue references, ptr got copied into
96         // the shared_ptr destructor and the copy was
97         // destroyed during unwinding.
98         assert(A::count == 0);
99         assert(B::count == 0);
100 #endif
101     }
102     }
103     assert(A::count == 0);
104 }
105