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