1// Copyright 2017 The Chromium Authors 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#include "base/memory/ref_counted_delete_on_sequence.h" 7 8namespace base { 9 10class Base : public RefCounted<Base> { 11 private: 12 friend class RefCounted<Base>; 13 14 ~Base() = default; 15}; 16 17class ThreadSafeBase : public RefCountedThreadSafe<ThreadSafeBase> { 18 private: 19 friend class RefCountedThreadSafe<ThreadSafeBase>; 20 21 ~ThreadSafeBase() = default; 22}; 23 24class DeleteOnSequenceBase 25 : public RefCountedDeleteOnSequence<DeleteOnSequenceBase> { 26 private: 27 friend class RefCountedDeleteOnSequence<DeleteOnSequenceBase>; 28 friend class DeleteHelper<DeleteOnSequenceBase>; 29 30 ~DeleteOnSequenceBase() = default; 31}; 32 33void AdoptRefToZeroStart() { 34 class InitialRefCountIsZero : public RefCounted<InitialRefCountIsZero> { 35 public: 36 InitialRefCountIsZero() = default; 37 38 private: 39 friend class RefCounted<InitialRefCountIsZero>; 40 41 ~InitialRefCountIsZero() = default; 42 }; 43 44 AdoptRef(new InitialRefCountIsZero()); // expected-error@*:* {{Use AdoptRef only if the reference count starts from one.}} 45} 46 47void WrongRefcountBaseClass() { 48 class Derived : public RefCounted<Base> { 49 private: 50 friend class RefCounted<Derived>; 51 52 ~Derived() = default; 53 }; 54 55 scoped_refptr<Derived> ptr; // expected-error@*:* {{T implements RefCounted<U>, but U is not a base of T.}} 56} 57 58void WrongRefcountThreadsafeBaseClass() { 59 class Derived : public RefCountedThreadSafe<ThreadSafeBase> { 60 private: 61 friend class RefCountedThreadSafe<Derived>; 62 63 ~Derived() = default; 64 }; 65 66 scoped_refptr<Derived> ptr; // expected-error@*:* {{T implements RefCountedThreadSafe<U>, but U is not a base of T.}} 67} 68 69void WrongRefcountDeleteOnSequenceBaseClass() { 70 class DeleteOnSequenceDerived 71 : public RefCountedDeleteOnSequence<DeleteOnSequenceBase> { 72 private: 73 friend class RefCountedDeleteOnSequence<DeleteOnSequenceDerived>; 74 friend class DeleteHelper<DeleteOnSequenceDerived>; 75 76 ~DeleteOnSequenceDerived() = default; 77 }; 78 79 scoped_refptr<DeleteOnSequenceDerived> ptr; // expected-error@*:* {{T implements RefCountedDeleteOnSequence<U>, but U is not a base of T.}} 80} 81 82void SubclassOverridesRefcountPreference() { 83 class Derived : public Base { 84 public: 85 REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); 86 }; 87 88 scoped_refptr<Derived> ptr; // expected-error@*:* {{It's unsafe to override the ref count preference. Please remove REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE from subclasses.}} 89} 90 91void SubclassOverridesRefcountPreferenceThreadsafe() { 92 class Derived : public ThreadSafeBase { 93 public: 94 REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); 95 }; 96 97 scoped_refptr<Derived> ptr; // expected-error@*:* {{It's unsafe to override the ref count preference. Please remove REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE from subclasses.}} 98} 99 100void SubclassOverridesRefcountPreferenceDeleteOnSequence() { 101 class Derived : public DeleteOnSequenceBase { 102 public: 103 REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); 104 }; 105 106 scoped_refptr<Derived> ptr; // expected-error@*:* {{It's unsafe to override the ref count preference. Please remove REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE from subclasses.}} 107} 108 109} // namespace base 110