ref_counted_unittest.cc 22 KB

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