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 // <memory>
10
11 // shared_ptr
12
13 // template<class T, class... Args>
14 // shared_ptr<T> make_shared(Args&&... args); // T is not an array
15
16 #include <memory>
17 #include <cassert>
18
19 #include "count_new.h"
20 #include "operator_hijacker.h"
21 #include "test_macros.h"
22
23 struct A
24 {
25 static int count;
26
AA27 A(int i, char c) : int_(i), char_(c) {++count;}
AA28 A(const A& a)
29 : int_(a.int_), char_(a.char_)
30 {++count;}
~AA31 ~A() {--count;}
32
get_intA33 int get_int() const {return int_;}
get_charA34 char get_char() const {return char_;}
35
36 A* operator& () = delete;
37
38 private:
39 int int_;
40 char char_;
41 };
42
43 int A::count = 0;
44
45
46 struct Foo
47 {
48 Foo() = default;
49 virtual ~Foo() = default;
50 };
51
52 #ifdef _LIBCPP_VERSION
53 struct Result {};
theFunction()54 static Result theFunction() { return Result(); }
55 static int resultDeletorCount;
resultDeletor(Result (* pf)())56 static void resultDeletor(Result (*pf)()) {
57 assert(pf == theFunction);
58 ++resultDeletorCount;
59 }
60
test_pointer_to_function()61 void test_pointer_to_function() {
62 { // https://llvm.org/PR27566
63 std::shared_ptr<Result()> x(&theFunction, &resultDeletor);
64 std::shared_ptr<Result()> y(theFunction, resultDeletor);
65 }
66 assert(resultDeletorCount == 2);
67 }
68 #else // _LIBCPP_VERSION
test_pointer_to_function()69 void test_pointer_to_function() {}
70 #endif // _LIBCPP_VERSION
71
72 template <typename T>
test(const T & t0)73 void test(const T &t0)
74 {
75 {
76 T t1 = t0;
77 std::shared_ptr<T> p0 = std::make_shared<T>(t0);
78 std::shared_ptr<T> p1 = std::make_shared<T>(t1);
79 assert(*p0 == t0);
80 assert(*p1 == t1);
81 }
82
83 {
84 const T t1 = t0;
85 std::shared_ptr<const T> p0 = std::make_shared<const T>(t0);
86 std::shared_ptr<const T> p1 = std::make_shared<const T>(t1);
87 assert(*p0 == t0);
88 assert(*p1 == t1);
89 }
90 }
91
main(int,char **)92 int main(int, char**)
93 {
94 int nc = globalMemCounter.outstanding_new;
95 {
96 int i = 67;
97 char c = 'e';
98 std::shared_ptr<A> p = std::make_shared<A>(i, c);
99 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(nc+1));
100 assert(A::count == 1);
101 assert(p->get_int() == 67);
102 assert(p->get_char() == 'e');
103 }
104
105 { // https://llvm.org/PR24137
106 std::shared_ptr<Foo> p1 = std::make_shared<Foo>();
107 assert(p1.get());
108 std::shared_ptr<const Foo> p2 = std::make_shared<const Foo>();
109 assert(p2.get());
110 }
111
112 test_pointer_to_function();
113
114 #if TEST_STD_VER >= 11
115 nc = globalMemCounter.outstanding_new;
116 {
117 char c = 'e';
118 std::shared_ptr<A> p = std::make_shared<A>(67, c);
119 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(nc+1));
120 assert(A::count == 1);
121 assert(p->get_int() == 67);
122 assert(p->get_char() == 'e');
123 }
124 #endif
125 assert(A::count == 0);
126
127 // Make sure std::make_shared handles badly-behaved types properly
128 {
129 std::shared_ptr<operator_hijacker> p1 = std::make_shared<operator_hijacker>();
130 std::shared_ptr<operator_hijacker> p2 = std::make_shared<operator_hijacker>(operator_hijacker());
131 assert(p1 != nullptr);
132 assert(p2 != nullptr);
133 }
134
135 test<bool>(true);
136 test<int>(3);
137 test<double>(5.0);
138
139 return 0;
140 }
141