1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/fxcrt/unowned_ptr.h"
6
7 #include <utility>
8 #include <vector>
9
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/base/ptr_util.h"
12
13 namespace fxcrt {
14 namespace {
15
16 class Clink {
17 public:
18 UnownedPtr<Clink> next_ = nullptr;
19 };
20
DeleteDangling()21 void DeleteDangling() {
22 auto ptr2 = pdfium::MakeUnique<Clink>();
23 {
24 auto ptr1 = pdfium::MakeUnique<Clink>();
25 ptr2->next_ = ptr1.get();
26 }
27 }
28
ResetDangling()29 void ResetDangling() {
30 auto ptr2 = pdfium::MakeUnique<Clink>();
31 {
32 auto ptr1 = pdfium::MakeUnique<Clink>();
33 ptr2->next_.Reset(ptr1.get());
34 }
35 ptr2->next_.Reset();
36 }
37
AssignDangling()38 void AssignDangling() {
39 auto ptr2 = pdfium::MakeUnique<Clink>();
40 {
41 auto ptr1 = pdfium::MakeUnique<Clink>();
42 ptr2->next_ = ptr1.get();
43 }
44 ptr2->next_ = nullptr;
45 }
46
ReleaseDangling()47 void ReleaseDangling() {
48 auto ptr2 = pdfium::MakeUnique<Clink>();
49 {
50 auto ptr1 = pdfium::MakeUnique<Clink>();
51 ptr2->next_ = ptr1.get();
52 }
53 ptr2->next_.Release();
54 }
55
56 } // namespace
57
TEST(UnownedPtr,PtrOk)58 TEST(UnownedPtr, PtrOk) {
59 auto ptr1 = pdfium::MakeUnique<Clink>();
60 {
61 auto ptr2 = pdfium::MakeUnique<Clink>();
62 ptr2->next_ = ptr1.get();
63 }
64 }
65
TEST(UnownedPtr,PtrNotOk)66 TEST(UnownedPtr, PtrNotOk) {
67 #if defined(ADDRESS_SANITIZER)
68 EXPECT_DEATH(DeleteDangling(), "");
69 #else
70 DeleteDangling();
71 #endif
72 }
73
TEST(UnownedPtr,ResetOk)74 TEST(UnownedPtr, ResetOk) {
75 auto ptr1 = pdfium::MakeUnique<Clink>();
76 {
77 auto ptr2 = pdfium::MakeUnique<Clink>();
78 ptr2->next_.Reset(ptr1.get());
79 ptr2->next_.Reset(nullptr);
80 }
81 }
82
TEST(UnownedPtr,ResetNotOk)83 TEST(UnownedPtr, ResetNotOk) {
84 #if defined(ADDRESS_SANITIZER)
85 EXPECT_DEATH(ResetDangling(), "");
86 #else
87 ResetDangling();
88 #endif
89 }
90
TEST(UnownedPtr,AssignOk)91 TEST(UnownedPtr, AssignOk) {
92 auto ptr1 = pdfium::MakeUnique<Clink>();
93 {
94 auto ptr2 = pdfium::MakeUnique<Clink>();
95 ptr2->next_ = ptr1.get();
96 ptr2->next_ = nullptr;
97 }
98 }
99
TEST(UnownedPtr,AssignNotOk)100 TEST(UnownedPtr, AssignNotOk) {
101 #if defined(ADDRESS_SANITIZER)
102 EXPECT_DEATH(AssignDangling(), "");
103 #else
104 AssignDangling();
105 #endif
106 }
107
TEST(UnownedPtr,ReleaseOk)108 TEST(UnownedPtr, ReleaseOk) {
109 auto ptr2 = pdfium::MakeUnique<Clink>();
110 {
111 auto ptr1 = pdfium::MakeUnique<Clink>();
112 ptr2->next_ = ptr1.get();
113 ptr2->next_.Release();
114 }
115 }
116
TEST(UnownedPtr,MoveCtorOk)117 TEST(UnownedPtr, MoveCtorOk) {
118 UnownedPtr<Clink> outer;
119 {
120 auto owned = pdfium::MakeUnique<Clink>();
121 outer = owned.get();
122 UnownedPtr<Clink> inner(std::move(outer));
123 EXPECT_EQ(nullptr, outer.Get());
124 }
125 }
126
TEST(UnownedPtr,MoveAssignOk)127 TEST(UnownedPtr, MoveAssignOk) {
128 UnownedPtr<Clink> outer;
129 {
130 auto owned = pdfium::MakeUnique<Clink>();
131 outer = owned.get();
132 UnownedPtr<Clink> inner;
133 inner = std::move(outer);
134 EXPECT_EQ(nullptr, outer.Get());
135 }
136 }
137
TEST(UnownedPtr,ReleaseNotOk)138 TEST(UnownedPtr, ReleaseNotOk) {
139 #if defined(ADDRESS_SANITIZER)
140 EXPECT_DEATH(ReleaseDangling(), "");
141 #else
142 ReleaseDangling();
143 #endif
144 }
145
TEST(UnownedPtr,OperatorEQ)146 TEST(UnownedPtr, OperatorEQ) {
147 int foo;
148 UnownedPtr<int> ptr1;
149 EXPECT_TRUE(ptr1 == ptr1);
150
151 UnownedPtr<int> ptr2;
152 EXPECT_TRUE(ptr1 == ptr2);
153
154 UnownedPtr<int> ptr3(&foo);
155 EXPECT_TRUE(&foo == ptr3);
156 EXPECT_TRUE(ptr3 == &foo);
157 EXPECT_FALSE(ptr1 == ptr3);
158
159 ptr1 = &foo;
160 EXPECT_TRUE(ptr1 == ptr3);
161 }
162
TEST(UnownedPtr,OperatorNE)163 TEST(UnownedPtr, OperatorNE) {
164 int foo;
165 UnownedPtr<int> ptr1;
166 EXPECT_FALSE(ptr1 != ptr1);
167
168 UnownedPtr<int> ptr2;
169 EXPECT_FALSE(ptr1 != ptr2);
170
171 UnownedPtr<int> ptr3(&foo);
172 EXPECT_FALSE(&foo != ptr3);
173 EXPECT_FALSE(ptr3 != &foo);
174 EXPECT_TRUE(ptr1 != ptr3);
175
176 ptr1 = &foo;
177 EXPECT_FALSE(ptr1 != ptr3);
178 }
179
TEST(UnownedPtr,OperatorLT)180 TEST(UnownedPtr, OperatorLT) {
181 int foos[2];
182 UnownedPtr<int> ptr1(&foos[0]);
183 UnownedPtr<int> ptr2(&foos[1]);
184
185 EXPECT_FALSE(ptr1 < ptr1);
186 EXPECT_TRUE(ptr1 < ptr2);
187 EXPECT_FALSE(ptr2 < ptr1);
188 }
189
190 } // namespace fxcrt
191