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