1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: sanitizer-new-delete
10 
11 // <memory>
12 
13 // template <class Y, class D> shared_ptr(unique_ptr<Y, D>&&r);
14 
15 #include <memory>
16 #include <new>
17 #include <cstdlib>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 #include "count_new.h"
22 
23 struct B
24 {
25     static int count;
26 
BB27     B() {++count;}
BB28     B(const B&) {++count;}
~BB29     virtual ~B() {--count;}
30 };
31 
32 int B::count = 0;
33 
34 struct A
35     : public B
36 {
37     static int count;
38 
AA39     A() {++count;}
AA40     A(const A& other) : B(other) {++count;}
~AA41     ~A() {--count;}
42 };
43 
44 int A::count = 0;
45 
fn(const std::shared_ptr<int> &)46 void fn ( const std::shared_ptr<int> &) {}
fn(const std::shared_ptr<B> &)47 void fn ( const std::shared_ptr<B> &) { assert (false); }
48 
49 template <typename T>
assert_deleter(T *)50 void assert_deleter ( T * ) { assert(false); }
51 
52 namespace adl {
53 struct D {
operator ()adl::D54     void operator()(int *) const {}
55 };
56 void ref(D);
57 }
58 
59 template <class T>
60 struct StatefulDeleter {
61   int state = 0;
62 
StatefulDeleterStatefulDeleter63   StatefulDeleter(int val = 0) : state(val) {}
StatefulDeleterStatefulDeleter64   StatefulDeleter(StatefulDeleter const&) { assert(false); }
65 
operator ()StatefulDeleter66   void operator()(T* ptr) {
67     assert(state == 42);
68     delete ptr;
69   }
70 };
71 
72 template <class T>
73 struct StatefulArrayDeleter {
74   int state = 0;
75 
StatefulArrayDeleterStatefulArrayDeleter76   StatefulArrayDeleter(int val = 0) : state(val) {}
StatefulArrayDeleterStatefulArrayDeleter77   StatefulArrayDeleter(StatefulArrayDeleter const&) { assert(false); }
78 
operator ()StatefulArrayDeleter79   void operator()(T* ptr) {
80     assert(state == 42);
81     delete []ptr;
82   }
83 };
84 
85 struct MovingDeleter {
MovingDeleterMovingDeleter86   explicit MovingDeleter(int *moves) : moves_(moves) {}
MovingDeleterMovingDeleter87   MovingDeleter(MovingDeleter&& rhs) : moves_(rhs.moves_) { *moves_ += 1; }
operator ()MovingDeleter88   void operator()(int*) const {}
89   int *moves_;
90 };
91 
main(int,char **)92 int main(int, char**)
93 {
94     {
95         std::unique_ptr<A> ptr(new A);
96         A* raw_ptr = ptr.get();
97         std::shared_ptr<B> p(std::move(ptr));
98         assert(A::count == 1);
99         assert(B::count == 1);
100         assert(p.use_count() == 1);
101         assert(p.get() == raw_ptr);
102         assert(ptr.get() == 0);
103     }
104 
105     {
106         std::unique_ptr<A const> ptr(new A);
107         A const* raw_ptr = ptr.get();
108         std::shared_ptr<B const> p(std::move(ptr));
109         assert(A::count == 1);
110         assert(B::count == 1);
111         assert(p.use_count() == 1);
112         assert(p.get() == raw_ptr);
113         assert(ptr.get() == 0);
114     }
115 
116 #ifndef TEST_HAS_NO_EXCEPTIONS
117     assert(A::count == 0);
118     {
119         std::unique_ptr<A> ptr(new A);
120         A* raw_ptr = ptr.get();
121         globalMemCounter.throw_after = 0;
122         try
123         {
124             std::shared_ptr<B> p(std::move(ptr));
125             assert(false);
126         }
127         catch (...)
128         {
129             assert(A::count == 1);
130             assert(B::count == 1);
131             assert(ptr.get() == raw_ptr);
132         }
133     }
134 #endif
135 
136 #if TEST_STD_VER > 14
137     {
138       std::unique_ptr<int> ptr;
139       std::shared_ptr<int> p(std::move(ptr));
140       assert(p.get() == 0);
141       assert(p.use_count() == 0);
142     }
143 #endif
144 
145     {
146       StatefulDeleter<A> d;
147       std::unique_ptr<A, StatefulDeleter<A>&> u(new A, d);
148       std::shared_ptr<A> p(std::move(u));
149       d.state = 42;
150       assert(A::count == 1);
151     }
152     assert(A::count == 0);
153 
154     { // LWG 2399
155         fn(std::unique_ptr<int>(new int));
156     }
157 #if TEST_STD_VER >= 14
158     { // LWG 2415
159         std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>);
160         std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope
161     }
162 #endif
163 
164     {
165     adl::D d;
166     std::unique_ptr<int, adl::D&> u(nullptr, d);
167     std::shared_ptr<int> s = std::move(u);
168     }
169 
170     assert(A::count == 0);
171 #ifdef _LIBCPP_VERSION // https://llvm.org/PR53368
172     {
173       std::unique_ptr<A[]> ptr(new A[8]);
174       A* raw_ptr = ptr.get();
175       std::shared_ptr<B> p(std::move(ptr));
176       assert(A::count == 8);
177       assert(B::count == 8);
178       assert(p.use_count() == 1);
179       assert(p.get() == raw_ptr);
180       assert(ptr.get() == 0);
181     }
182     assert(A::count == 0);
183     assert(B::count == 0);
184 
185     {
186       std::unique_ptr<A[]> ptr(new A[8]);
187       A* raw_ptr = ptr.get();
188       std::shared_ptr<A> p(std::move(ptr));
189       assert(A::count == 8);
190       assert(p.use_count() == 1);
191       assert(p.get() == raw_ptr);
192       assert(ptr.get() == 0);
193     }
194     assert(A::count == 0);
195 
196     {
197       std::unique_ptr<int[]> ptr(new int[8]);
198       std::shared_ptr<int> p(std::move(ptr));
199     }
200 #endif // _LIBCPP_VERSION
201 
202 #if TEST_STD_VER > 14
203     {
204       StatefulArrayDeleter<A> d;
205       std::unique_ptr<A[], StatefulArrayDeleter<A>&> u(new A[4], d);
206       std::shared_ptr<A[]> p(std::move(u));
207       d.state = 42;
208       assert(A::count == 4);
209     }
210     assert(A::count == 0);
211     assert(B::count == 0);
212 
213 #ifdef _LIBCPP_VERSION // https://llvm.org/PR53368
214     {
215       std::unique_ptr<A[]> ptr(new A[8]);
216       A* raw_ptr = ptr.get();
217       std::shared_ptr<B[]> p(std::move(ptr));
218       assert(A::count == 8);
219       assert(B::count == 8);
220       assert(p.use_count() == 1);
221       assert(p.get() == raw_ptr);
222       assert(ptr.get() == 0);
223     }
224     assert(A::count == 0);
225     assert(B::count == 0);
226 #endif // _LIBCPP_VERSION
227 
228     {
229       std::unique_ptr<A[]> ptr(new A[8]);
230       A* raw_ptr = ptr.get();
231       std::shared_ptr<A[]> p(std::move(ptr));
232       assert(A::count == 8);
233       assert(p.use_count() == 1);
234       assert(p.get() == raw_ptr);
235       assert(ptr.get() == 0);
236     }
237     assert(A::count == 0);
238 
239     {
240       int *p = new int[8];
241       std::unique_ptr<int[]> u(p);
242       std::shared_ptr<int[]> s(std::move(u));
243       assert(u == nullptr);
244       assert(s.get() == p);
245     }
246 #endif // TEST_STD_VER > 14
247 
248     { // LWG 3548
249       {
250         int moves = 0;
251         int i = 42;
252         std::unique_ptr<int, MovingDeleter> u(&i, MovingDeleter(&moves));
253         assert(moves == 1);
254         std::shared_ptr<int> s(std::move(u));
255         assert(moves >= 2);
256         assert(u == nullptr);
257         assert(s.get() == &i);
258       }
259 
260 #if TEST_STD_VER > 14
261       {
262         int moves = 0;
263         int a[8];
264         std::unique_ptr<int[], MovingDeleter> u(a, MovingDeleter(&moves));
265         assert(moves == 1);
266         std::shared_ptr<int[]> s = std::move(u);
267         assert(moves >= 2);
268         assert(u == nullptr);
269         assert(s.get() == a);
270       }
271 #endif // TEST_STD_VER > 14
272     }
273 
274     return 0;
275 }
276