Home | History | Annotate | Download | only in memory
      1 // Copyright (c) 2012 The Chromium 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 "base/memory/ref_counted.h"
      6 
      7 #include <type_traits>
      8 #include <utility>
      9 
     10 #include "base/test/gtest_util.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 namespace {
     14 
     15 class SelfAssign : public base::RefCounted<SelfAssign> {
     16  protected:
     17   virtual ~SelfAssign() = default;
     18 
     19  private:
     20   friend class base::RefCounted<SelfAssign>;
     21 };
     22 
     23 class Derived : public SelfAssign {
     24  protected:
     25   ~Derived() override = default;
     26 
     27  private:
     28   friend class base::RefCounted<Derived>;
     29 };
     30 
     31 class CheckDerivedMemberAccess : public scoped_refptr<SelfAssign> {
     32  public:
     33   CheckDerivedMemberAccess() {
     34     // This shouldn't compile if we don't have access to the member variable.
     35     SelfAssign** pptr = &ptr_;
     36     EXPECT_EQ(*pptr, ptr_);
     37   }
     38 };
     39 
     40 class ScopedRefPtrToSelf : public base::RefCounted<ScopedRefPtrToSelf> {
     41  public:
     42   ScopedRefPtrToSelf() : self_ptr_(this) {}
     43 
     44   static bool was_destroyed() { return was_destroyed_; }
     45 
     46   static void reset_was_destroyed() { was_destroyed_ = false; }
     47 
     48   scoped_refptr<ScopedRefPtrToSelf> self_ptr_;
     49 
     50  private:
     51   friend class base::RefCounted<ScopedRefPtrToSelf>;
     52   ~ScopedRefPtrToSelf() { was_destroyed_ = true; }
     53 
     54   static bool was_destroyed_;
     55 };
     56 
     57 bool ScopedRefPtrToSelf::was_destroyed_ = false;
     58 
     59 class ScopedRefPtrCountBase : public base::RefCounted<ScopedRefPtrCountBase> {
     60  public:
     61   ScopedRefPtrCountBase() { ++constructor_count_; }
     62 
     63   static int constructor_count() { return constructor_count_; }
     64 
     65   static int destructor_count() { return destructor_count_; }
     66 
     67   static void reset_count() {
     68     constructor_count_ = 0;
     69     destructor_count_ = 0;
     70   }
     71 
     72  protected:
     73   virtual ~ScopedRefPtrCountBase() { ++destructor_count_; }
     74 
     75  private:
     76   friend class base::RefCounted<ScopedRefPtrCountBase>;
     77 
     78   static int constructor_count_;
     79   static int destructor_count_;
     80 };
     81 
     82 int ScopedRefPtrCountBase::constructor_count_ = 0;
     83 int ScopedRefPtrCountBase::destructor_count_ = 0;
     84 
     85 class ScopedRefPtrCountDerived : public ScopedRefPtrCountBase {
     86  public:
     87   ScopedRefPtrCountDerived() { ++constructor_count_; }
     88 
     89   static int constructor_count() { return constructor_count_; }
     90 
     91   static int destructor_count() { return destructor_count_; }
     92 
     93   static void reset_count() {
     94     constructor_count_ = 0;
     95     destructor_count_ = 0;
     96   }
     97 
     98  protected:
     99   ~ScopedRefPtrCountDerived() override { ++destructor_count_; }
    100 
    101  private:
    102   friend class base::RefCounted<ScopedRefPtrCountDerived>;
    103 
    104   static int constructor_count_;
    105   static int destructor_count_;
    106 };
    107 
    108 int ScopedRefPtrCountDerived::constructor_count_ = 0;
    109 int ScopedRefPtrCountDerived::destructor_count_ = 0;
    110 
    111 class Other : public base::RefCounted<Other> {
    112  private:
    113   friend class base::RefCounted<Other>;
    114 
    115   ~Other() = default;
    116 };
    117 
    118 class HasPrivateDestructorWithDeleter;
    119 
    120 struct Deleter {
    121   static void Destruct(const HasPrivateDestructorWithDeleter* x);
    122 };
    123 
    124 class HasPrivateDestructorWithDeleter
    125     : public base::RefCounted<HasPrivateDestructorWithDeleter, Deleter> {
    126  public:
    127   HasPrivateDestructorWithDeleter() = default;
    128 
    129  private:
    130   friend struct Deleter;
    131   ~HasPrivateDestructorWithDeleter() = default;
    132 };
    133 
    134 void Deleter::Destruct(const HasPrivateDestructorWithDeleter* x) {
    135   delete x;
    136 }
    137 
    138 scoped_refptr<Other> Overloaded(scoped_refptr<Other> other) {
    139   return other;
    140 }
    141 
    142 scoped_refptr<SelfAssign> Overloaded(scoped_refptr<SelfAssign> self_assign) {
    143   return self_assign;
    144 }
    145 
    146 class InitialRefCountIsOne : public base::RefCounted<InitialRefCountIsOne> {
    147  public:
    148   REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
    149 
    150   InitialRefCountIsOne() = default;
    151 
    152  private:
    153   friend class base::RefCounted<InitialRefCountIsOne>;
    154   ~InitialRefCountIsOne() = default;
    155 };
    156 
    157 // Checks that the scoped_refptr is null before the reference counted object is
    158 // destroyed.
    159 class CheckRefptrNull : public base::RefCounted<CheckRefptrNull> {
    160  public:
    161   // Set the last scoped_refptr that will have a reference to this object.
    162   void set_scoped_refptr(scoped_refptr<CheckRefptrNull>* ptr) { ptr_ = ptr; }
    163 
    164  protected:
    165   virtual ~CheckRefptrNull() {
    166     EXPECT_NE(ptr_, nullptr);
    167     EXPECT_EQ(ptr_->get(), nullptr);
    168   }
    169 
    170  private:
    171   friend class base::RefCounted<CheckRefptrNull>;
    172 
    173   scoped_refptr<CheckRefptrNull>* ptr_ = nullptr;
    174 };
    175 
    176 }  // end namespace
    177 
    178 TEST(RefCountedUnitTest, TestSelfAssignment) {
    179   SelfAssign* p = new SelfAssign;
    180   scoped_refptr<SelfAssign> var(p);
    181   var = *&var;  // The *& defeats Clang's -Wself-assign warning.
    182   EXPECT_EQ(var.get(), p);
    183   var = std::move(var);
    184   EXPECT_EQ(var.get(), p);
    185   var.swap(var);
    186   EXPECT_EQ(var.get(), p);
    187   swap(var, var);
    188   EXPECT_EQ(var.get(), p);
    189 }
    190 
    191 TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) {
    192   CheckDerivedMemberAccess check;
    193 }
    194 
    195 TEST(RefCountedUnitTest, ScopedRefPtrToSelfPointerAssignment) {
    196   ScopedRefPtrToSelf::reset_was_destroyed();
    197 
    198   ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
    199   EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
    200   check->self_ptr_ = nullptr;
    201   EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
    202 }
    203 
    204 TEST(RefCountedUnitTest, ScopedRefPtrToSelfMoveAssignment) {
    205   ScopedRefPtrToSelf::reset_was_destroyed();
    206 
    207   ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
    208   EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
    209   // Releasing |check->self_ptr_| will delete |check|.
    210   // The move assignment operator must assign |check->self_ptr_| first then
    211   // release |check->self_ptr_|.
    212   check->self_ptr_ = scoped_refptr<ScopedRefPtrToSelf>();
    213   EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
    214 }
    215 
    216 TEST(RefCountedUnitTest, BooleanTesting) {
    217   scoped_refptr<SelfAssign> ptr_to_an_instance = new SelfAssign;
    218   EXPECT_TRUE(ptr_to_an_instance);
    219   EXPECT_FALSE(!ptr_to_an_instance);
    220 
    221   if (ptr_to_an_instance) {
    222   } else {
    223     ADD_FAILURE() << "Pointer to an instance should result in true.";
    224   }
    225 
    226   if (!ptr_to_an_instance) {  // check for operator!().
    227     ADD_FAILURE() << "Pointer to an instance should result in !x being false.";
    228   }
    229 
    230   scoped_refptr<SelfAssign> null_ptr;
    231   EXPECT_FALSE(null_ptr);
    232   EXPECT_TRUE(!null_ptr);
    233 
    234   if (null_ptr) {
    235     ADD_FAILURE() << "Null pointer should result in false.";
    236   }
    237 
    238   if (!null_ptr) {  // check for operator!().
    239   } else {
    240     ADD_FAILURE() << "Null pointer should result in !x being true.";
    241   }
    242 }
    243 
    244 TEST(RefCountedUnitTest, Equality) {
    245   scoped_refptr<SelfAssign> p1(new SelfAssign);
    246   scoped_refptr<SelfAssign> p2(new SelfAssign);
    247 
    248   EXPECT_EQ(p1, p1);
    249   EXPECT_EQ(p2, p2);
    250 
    251   EXPECT_NE(p1, p2);
    252   EXPECT_NE(p2, p1);
    253 }
    254 
    255 TEST(RefCountedUnitTest, NullptrEquality) {
    256   scoped_refptr<SelfAssign> ptr_to_an_instance(new SelfAssign);
    257   scoped_refptr<SelfAssign> ptr_to_nullptr;
    258 
    259   EXPECT_NE(nullptr, ptr_to_an_instance);
    260   EXPECT_NE(ptr_to_an_instance, nullptr);
    261   EXPECT_EQ(nullptr, ptr_to_nullptr);
    262   EXPECT_EQ(ptr_to_nullptr, nullptr);
    263 }
    264 
    265 TEST(RefCountedUnitTest, ConvertibleEquality) {
    266   scoped_refptr<Derived> p1(new Derived);
    267   scoped_refptr<SelfAssign> p2;
    268 
    269   EXPECT_NE(p1, p2);
    270   EXPECT_NE(p2, p1);
    271 
    272   p2 = p1;
    273 
    274   EXPECT_EQ(p1, p2);
    275   EXPECT_EQ(p2, p1);
    276 }
    277 
    278 TEST(RefCountedUnitTest, MoveAssignment1) {
    279   ScopedRefPtrCountBase::reset_count();
    280 
    281   {
    282     ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
    283     scoped_refptr<ScopedRefPtrCountBase> p1(raw);
    284     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    285     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    286 
    287     {
    288       scoped_refptr<ScopedRefPtrCountBase> p2;
    289 
    290       p2 = std::move(p1);
    291       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    292       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    293       EXPECT_EQ(nullptr, p1.get());
    294       EXPECT_EQ(raw, p2.get());
    295 
    296       // p2 goes out of scope.
    297     }
    298     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    299     EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    300 
    301     // p1 goes out of scope.
    302   }
    303   EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    304   EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    305 }
    306 
    307 TEST(RefCountedUnitTest, MoveAssignment2) {
    308   ScopedRefPtrCountBase::reset_count();
    309 
    310   {
    311     ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
    312     scoped_refptr<ScopedRefPtrCountBase> p1;
    313     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    314     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    315 
    316     {
    317       scoped_refptr<ScopedRefPtrCountBase> p2(raw);
    318       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    319       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    320 
    321       p1 = std::move(p2);
    322       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    323       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    324       EXPECT_EQ(raw, p1.get());
    325       EXPECT_EQ(nullptr, p2.get());
    326 
    327       // p2 goes out of scope.
    328     }
    329     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    330     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    331 
    332     // p1 goes out of scope.
    333   }
    334   EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    335   EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    336 }
    337 
    338 TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) {
    339   ScopedRefPtrCountBase::reset_count();
    340 
    341   {
    342     ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
    343     scoped_refptr<ScopedRefPtrCountBase> p1(raw);
    344     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    345     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    346 
    347     {
    348       scoped_refptr<ScopedRefPtrCountBase> p2(p1);
    349       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    350       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    351 
    352       p1 = std::move(p2);
    353       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    354       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    355       EXPECT_EQ(raw, p1.get());
    356       EXPECT_EQ(nullptr, p2.get());
    357 
    358       // p2 goes out of scope.
    359     }
    360     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    361     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    362 
    363     // p1 goes out of scope.
    364   }
    365   EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    366   EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    367 }
    368 
    369 TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) {
    370   ScopedRefPtrCountBase::reset_count();
    371 
    372   {
    373     ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
    374     scoped_refptr<ScopedRefPtrCountBase> p1(raw);
    375     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    376     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    377 
    378     {
    379       scoped_refptr<ScopedRefPtrCountBase> p2(p1);
    380       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    381       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    382 
    383       p2 = std::move(p1);
    384       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    385       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    386       EXPECT_EQ(nullptr, p1.get());
    387       EXPECT_EQ(raw, p2.get());
    388 
    389       // p2 goes out of scope.
    390     }
    391     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    392     EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    393 
    394     // p1 goes out of scope.
    395   }
    396   EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    397   EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    398 }
    399 
    400 TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) {
    401   ScopedRefPtrCountBase::reset_count();
    402 
    403   {
    404     ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
    405     scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
    406     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    407     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    408 
    409     {
    410       ScopedRefPtrCountBase *raw2 = new ScopedRefPtrCountBase();
    411       scoped_refptr<ScopedRefPtrCountBase> p2(raw2);
    412       EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    413       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    414 
    415       p1 = std::move(p2);
    416       EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    417       EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    418       EXPECT_EQ(raw2, p1.get());
    419       EXPECT_EQ(nullptr, p2.get());
    420 
    421       // p2 goes out of scope.
    422     }
    423     EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    424     EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    425 
    426     // p1 goes out of scope.
    427   }
    428   EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    429   EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
    430 }
    431 
    432 TEST(RefCountedUnitTest, MoveAssignmentSelfMove) {
    433   ScopedRefPtrCountBase::reset_count();
    434 
    435   {
    436     ScopedRefPtrCountBase* raw = new ScopedRefPtrCountBase;
    437     scoped_refptr<ScopedRefPtrCountBase> p1(raw);
    438     scoped_refptr<ScopedRefPtrCountBase>& p1_ref = p1;
    439 
    440     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    441     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    442 
    443     p1 = std::move(p1_ref);
    444 
    445     // |p1| is "valid but unspecified", so don't bother inspecting its
    446     // contents, just ensure that we don't crash.
    447   }
    448 
    449   EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    450   EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    451 }
    452 
    453 TEST(RefCountedUnitTest, MoveAssignmentDerived) {
    454   ScopedRefPtrCountBase::reset_count();
    455   ScopedRefPtrCountDerived::reset_count();
    456 
    457   {
    458     ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
    459     scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
    460     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    461     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    462     EXPECT_EQ(0, ScopedRefPtrCountDerived::constructor_count());
    463     EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
    464 
    465     {
    466       ScopedRefPtrCountDerived *raw2 = new ScopedRefPtrCountDerived();
    467       scoped_refptr<ScopedRefPtrCountDerived> p2(raw2);
    468       EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    469       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    470       EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    471       EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
    472 
    473       p1 = std::move(p2);
    474       EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    475       EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    476       EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    477       EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
    478       EXPECT_EQ(raw2, p1.get());
    479       EXPECT_EQ(nullptr, p2.get());
    480 
    481       // p2 goes out of scope.
    482     }
    483     EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    484     EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    485     EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    486     EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
    487 
    488     // p1 goes out of scope.
    489   }
    490   EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
    491   EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
    492   EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    493   EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
    494 }
    495 
    496 TEST(RefCountedUnitTest, MoveConstructor) {
    497   ScopedRefPtrCountBase::reset_count();
    498 
    499   {
    500     ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
    501     scoped_refptr<ScopedRefPtrCountBase> p1(raw);
    502     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    503     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    504 
    505     {
    506       scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
    507       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    508       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    509       EXPECT_EQ(nullptr, p1.get());
    510       EXPECT_EQ(raw, p2.get());
    511 
    512       // p2 goes out of scope.
    513     }
    514     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    515     EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    516 
    517     // p1 goes out of scope.
    518   }
    519   EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    520   EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    521 }
    522 
    523 TEST(RefCountedUnitTest, MoveConstructorDerived) {
    524   ScopedRefPtrCountBase::reset_count();
    525   ScopedRefPtrCountDerived::reset_count();
    526 
    527   {
    528     ScopedRefPtrCountDerived *raw1 = new ScopedRefPtrCountDerived();
    529     scoped_refptr<ScopedRefPtrCountDerived> p1(raw1);
    530     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    531     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    532     EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    533     EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
    534 
    535     {
    536       scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
    537       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    538       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
    539       EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    540       EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
    541       EXPECT_EQ(nullptr, p1.get());
    542       EXPECT_EQ(raw1, p2.get());
    543 
    544       // p2 goes out of scope.
    545     }
    546     EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    547     EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    548     EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    549     EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
    550 
    551     // p1 goes out of scope.
    552   }
    553   EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
    554   EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
    555   EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
    556   EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
    557 }
    558 
    559 TEST(RefCountedUnitTest, TestOverloadResolutionCopy) {
    560   const scoped_refptr<Derived> derived(new Derived);
    561   const scoped_refptr<SelfAssign> expected(derived);
    562   EXPECT_EQ(expected, Overloaded(derived));
    563 
    564   const scoped_refptr<Other> other(new Other);
    565   EXPECT_EQ(other, Overloaded(other));
    566 }
    567 
    568 TEST(RefCountedUnitTest, TestOverloadResolutionMove) {
    569   scoped_refptr<Derived> derived(new Derived);
    570   const scoped_refptr<SelfAssign> expected(derived);
    571   EXPECT_EQ(expected, Overloaded(std::move(derived)));
    572 
    573   scoped_refptr<Other> other(new Other);
    574   const scoped_refptr<Other> other2(other);
    575   EXPECT_EQ(other2, Overloaded(std::move(other)));
    576 }
    577 
    578 TEST(RefCountedUnitTest, TestMakeRefCounted) {
    579   scoped_refptr<Derived> derived = new Derived;
    580   EXPECT_TRUE(derived->HasOneRef());
    581   derived.reset();
    582 
    583   scoped_refptr<Derived> derived2 = base::MakeRefCounted<Derived>();
    584   EXPECT_TRUE(derived2->HasOneRef());
    585   derived2.reset();
    586 }
    587 
    588 TEST(RefCountedUnitTest, TestInitialRefCountIsOne) {
    589   scoped_refptr<InitialRefCountIsOne> obj =
    590       base::MakeRefCounted<InitialRefCountIsOne>();
    591   EXPECT_TRUE(obj->HasOneRef());
    592   obj.reset();
    593 
    594   scoped_refptr<InitialRefCountIsOne> obj2 =
    595       base::AdoptRef(new InitialRefCountIsOne);
    596   EXPECT_TRUE(obj2->HasOneRef());
    597   obj2.reset();
    598 
    599   scoped_refptr<Other> obj3 = base::MakeRefCounted<Other>();
    600   EXPECT_TRUE(obj3->HasOneRef());
    601   obj3.reset();
    602 }
    603 
    604 TEST(RefCountedUnitTest, TestPrivateDestructorWithDeleter) {
    605   // Ensure that RefCounted doesn't need the access to the pointee dtor when
    606   // a custom deleter is given.
    607   scoped_refptr<HasPrivateDestructorWithDeleter> obj =
    608       base::MakeRefCounted<HasPrivateDestructorWithDeleter>();
    609 }
    610 
    611 TEST(RefCountedUnitTest, TestReset) {
    612   ScopedRefPtrCountBase::reset_count();
    613 
    614   // Create ScopedRefPtrCountBase that is referenced by |obj1| and |obj2|.
    615   scoped_refptr<ScopedRefPtrCountBase> obj1 =
    616       base::MakeRefCounted<ScopedRefPtrCountBase>();
    617   scoped_refptr<ScopedRefPtrCountBase> obj2 = obj1;
    618   EXPECT_NE(obj1.get(), nullptr);
    619   EXPECT_NE(obj2.get(), nullptr);
    620   EXPECT_EQ(ScopedRefPtrCountBase::constructor_count(), 1);
    621   EXPECT_EQ(ScopedRefPtrCountBase::destructor_count(), 0);
    622 
    623   // Check that calling reset() on |obj1| resets it. |obj2| still has a
    624   // reference to the ScopedRefPtrCountBase so it shouldn't be reset.
    625   obj1.reset();
    626   EXPECT_EQ(obj1.get(), nullptr);
    627   EXPECT_EQ(ScopedRefPtrCountBase::constructor_count(), 1);
    628   EXPECT_EQ(ScopedRefPtrCountBase::destructor_count(), 0);
    629 
    630   // Check that calling reset() on |obj2| resets it and causes the deletion of
    631   // the ScopedRefPtrCountBase.
    632   obj2.reset();
    633   EXPECT_EQ(obj2.get(), nullptr);
    634   EXPECT_EQ(ScopedRefPtrCountBase::constructor_count(), 1);
    635   EXPECT_EQ(ScopedRefPtrCountBase::destructor_count(), 1);
    636 }
    637 
    638 TEST(RefCountedUnitTest, TestResetAlreadyNull) {
    639   // Check that calling reset() on a null scoped_refptr does nothing.
    640   scoped_refptr<ScopedRefPtrCountBase> obj;
    641   obj.reset();
    642   // |obj| should still be null after calling reset().
    643   EXPECT_EQ(obj.get(), nullptr);
    644 }
    645 
    646 TEST(RefCountedUnitTest, CheckScopedRefptrNullBeforeObjectDestruction) {
    647   scoped_refptr<CheckRefptrNull> obj = base::MakeRefCounted<CheckRefptrNull>();
    648   obj->set_scoped_refptr(&obj);
    649 
    650   // Check that when reset() is called the scoped_refptr internal pointer is set
    651   // to null before the reference counted object is destroyed. This check is
    652   // done by the CheckRefptrNull destructor.
    653   obj.reset();
    654   EXPECT_EQ(obj.get(), nullptr);
    655 }
    656 
    657 TEST(RefCountedDeathTest, TestAdoptRef) {
    658   // Check that WrapRefCounted() DCHECKs if passed a type that defines
    659   // REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE.
    660   EXPECT_DCHECK_DEATH(base::WrapRefCounted(new InitialRefCountIsOne));
    661 
    662   // Check that AdoptRef() DCHECKs if passed a nullptr.
    663   InitialRefCountIsOne* ptr = nullptr;
    664   EXPECT_DCHECK_DEATH(base::AdoptRef(ptr));
    665 
    666   // Check that AdoptRef() DCHECKs if passed an object that doesn't need to be
    667   // adopted.
    668   scoped_refptr<InitialRefCountIsOne> obj =
    669       base::MakeRefCounted<InitialRefCountIsOne>();
    670   EXPECT_DCHECK_DEATH(base::AdoptRef(obj.get()));
    671 }
    672