blob: 5e09d9a7934c1f269879f0c14432611c2ba3db78 [file] [log] [blame]
Howard Hinnantc52f43e2010-08-22 00:59:46 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc52f43e2010-08-22 00:59:46 +00007//
8//===----------------------------------------------------------------------===//
9
10// <memory>
11
12// template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);
13
Eric Fiselier07a4bec2015-03-10 20:46:04 +000014// UNSUPPORTED: sanitizer-new-delete
Eric Fiselier72aab5f2014-11-04 05:11:41 +000015
Howard Hinnantc52f43e2010-08-22 00:59:46 +000016#include <memory>
17#include <new>
18#include <cstdlib>
19#include <cassert>
20
21bool throw_next = false;
22
23void* 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
30void operator delete(void* p) throw()
31{
32 std::free(p);
33}
34
35struct B
36{
37 static int count;
38
39 B() {++count;}
40 B(const B&) {++count;}
41 virtual ~B() {--count;}
42};
43
44int B::count = 0;
45
46struct A
47 : public B
48{
49 static int count;
50
51 A() {++count;}
52 A(const A&) {++count;}
53 ~A() {--count;}
54};
55
56int A::count = 0;
57
Marshall Clow7683fe22014-11-18 18:14:53 +000058void fn ( const std::shared_ptr<int> &) {}
59void fn ( const std::shared_ptr<B> &) { assert (false); }
60
Marshall Clow0ad232a2015-05-10 13:59:45 +000061template <typename T>
62void assert_deleter ( T * ) { assert(false); }
63
Howard Hinnantc52f43e2010-08-22 00:59:46 +000064int main()
65{
66 {
67 std::unique_ptr<A> ptr(new A);
68 A* raw_ptr = ptr.get();
69 std::shared_ptr<B> p(std::move(ptr));
70 assert(A::count == 1);
71 assert(B::count == 1);
72 assert(p.use_count() == 1);
73 assert(p.get() == raw_ptr);
74 assert(ptr.get() == 0);
75 }
76 assert(A::count == 0);
77 {
78 std::unique_ptr<A> ptr(new A);
79 A* raw_ptr = ptr.get();
80 throw_next = true;
81 try
82 {
83 std::shared_ptr<B> p(std::move(ptr));
84 assert(false);
85 }
86 catch (...)
87 {
Sean Hunt541cb302011-07-18 23:51:25 +000088#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000089 assert(A::count == 1);
90 assert(B::count == 1);
91 assert(ptr.get() == raw_ptr);
Sean Hunt541cb302011-07-18 23:51:25 +000092#else
93 assert(A::count == 0);
94 assert(B::count == 0);
95 assert(ptr.get() == 0);
96#endif
Howard Hinnantc52f43e2010-08-22 00:59:46 +000097 }
98 }
99 assert(A::count == 0);
Marshall Clow7683fe22014-11-18 18:14:53 +0000100
101 // LWG 2399
102 {
103 throw_next = false;
104 fn(std::unique_ptr<int>(new int));
105 }
Marshall Clow0ad232a2015-05-10 13:59:45 +0000106
107#if __cplusplus >= 201402L
108 // LWG 2415
109 {
110 std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>);
111 std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope
112 }
113#endif
114
Howard Hinnantc52f43e2010-08-22 00:59:46 +0000115}