| // Copyright 2017 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "core/fxcrt/unowned_ptr.h" |
| |
| #include <utility> |
| |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace fxcrt { |
| namespace { |
| |
| class Clink { |
| public: |
| UnownedPtr<Clink> next_ = nullptr; |
| }; |
| |
| void DeleteDangling() { |
| auto ptr2 = std::make_unique<Clink>(); |
| { |
| auto ptr1 = std::make_unique<Clink>(); |
| ptr2->next_ = ptr1.get(); |
| } |
| } |
| |
| void ResetDangling() { |
| auto ptr2 = std::make_unique<Clink>(); |
| { |
| auto ptr1 = std::make_unique<Clink>(); |
| ptr2->next_.Reset(ptr1.get()); |
| } |
| ptr2->next_.Reset(); |
| } |
| |
| void AssignDangling() { |
| auto ptr2 = std::make_unique<Clink>(); |
| { |
| auto ptr1 = std::make_unique<Clink>(); |
| ptr2->next_ = ptr1.get(); |
| } |
| ptr2->next_ = nullptr; |
| } |
| |
| void ReleaseDangling() { |
| auto ptr2 = std::make_unique<Clink>(); |
| { |
| auto ptr1 = std::make_unique<Clink>(); |
| ptr2->next_ = ptr1.get(); |
| } |
| ptr2->next_.Release(); |
| } |
| |
| } // namespace |
| |
| TEST(UnownedPtr, PtrOk) { |
| auto ptr1 = std::make_unique<Clink>(); |
| { |
| auto ptr2 = std::make_unique<Clink>(); |
| ptr2->next_ = ptr1.get(); |
| } |
| } |
| |
| TEST(UnownedPtr, PtrNotOk) { |
| #if defined(ADDRESS_SANITIZER) |
| EXPECT_DEATH(DeleteDangling(), ""); |
| #else |
| DeleteDangling(); |
| #endif |
| } |
| |
| TEST(UnownedPtr, ResetOk) { |
| auto ptr1 = std::make_unique<Clink>(); |
| { |
| auto ptr2 = std::make_unique<Clink>(); |
| ptr2->next_.Reset(ptr1.get()); |
| ptr2->next_.Reset(nullptr); |
| } |
| } |
| |
| TEST(UnownedPtr, ResetNotOk) { |
| #if defined(ADDRESS_SANITIZER) |
| EXPECT_DEATH(ResetDangling(), ""); |
| #else |
| ResetDangling(); |
| #endif |
| } |
| |
| TEST(UnownedPtr, AssignOk) { |
| auto ptr1 = std::make_unique<Clink>(); |
| { |
| auto ptr2 = std::make_unique<Clink>(); |
| ptr2->next_ = ptr1.get(); |
| ptr2->next_ = nullptr; |
| } |
| } |
| |
| TEST(UnownedPtr, AssignNotOk) { |
| #if defined(ADDRESS_SANITIZER) |
| EXPECT_DEATH(AssignDangling(), ""); |
| #else |
| AssignDangling(); |
| #endif |
| } |
| |
| TEST(UnownedPtr, ReleaseOk) { |
| auto ptr2 = std::make_unique<Clink>(); |
| { |
| auto ptr1 = std::make_unique<Clink>(); |
| ptr2->next_ = ptr1.get(); |
| ptr2->next_.Release(); |
| } |
| } |
| |
| TEST(UnownedPtr, MoveCtorOk) { |
| UnownedPtr<Clink> outer; |
| { |
| auto owned = std::make_unique<Clink>(); |
| outer = owned.get(); |
| UnownedPtr<Clink> inner(std::move(outer)); |
| EXPECT_EQ(nullptr, outer.Get()); |
| } |
| } |
| |
| TEST(UnownedPtr, MoveAssignOk) { |
| UnownedPtr<Clink> outer; |
| { |
| auto owned = std::make_unique<Clink>(); |
| outer = owned.get(); |
| UnownedPtr<Clink> inner; |
| inner = std::move(outer); |
| EXPECT_EQ(nullptr, outer.Get()); |
| } |
| } |
| |
| TEST(UnownedPtr, ReleaseNotOk) { |
| #if defined(ADDRESS_SANITIZER) |
| EXPECT_DEATH(ReleaseDangling(), ""); |
| #else |
| ReleaseDangling(); |
| #endif |
| } |
| |
| TEST(UnownedPtr, OperatorEQ) { |
| int foo; |
| UnownedPtr<int> ptr1; |
| EXPECT_TRUE(ptr1 == ptr1); |
| |
| UnownedPtr<int> ptr2; |
| EXPECT_TRUE(ptr1 == ptr2); |
| |
| UnownedPtr<int> ptr3(&foo); |
| EXPECT_TRUE(&foo == ptr3); |
| EXPECT_TRUE(ptr3 == &foo); |
| EXPECT_FALSE(ptr1 == ptr3); |
| |
| ptr1 = &foo; |
| EXPECT_TRUE(ptr1 == ptr3); |
| } |
| |
| TEST(UnownedPtr, OperatorNE) { |
| int foo; |
| UnownedPtr<int> ptr1; |
| EXPECT_FALSE(ptr1 != ptr1); |
| |
| UnownedPtr<int> ptr2; |
| EXPECT_FALSE(ptr1 != ptr2); |
| |
| UnownedPtr<int> ptr3(&foo); |
| EXPECT_FALSE(&foo != ptr3); |
| EXPECT_FALSE(ptr3 != &foo); |
| EXPECT_TRUE(ptr1 != ptr3); |
| |
| ptr1 = &foo; |
| EXPECT_FALSE(ptr1 != ptr3); |
| } |
| |
| TEST(UnownedPtr, OperatorLT) { |
| int foos[2]; |
| UnownedPtr<int> ptr1(&foos[0]); |
| UnownedPtr<int> ptr2(&foos[1]); |
| |
| EXPECT_FALSE(ptr1 < ptr1); |
| EXPECT_TRUE(ptr1 < ptr2); |
| EXPECT_FALSE(ptr2 < ptr1); |
| } |
| |
| } // namespace fxcrt |