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 #ifndef BASE_REFCOUNTED_H_ 6 #define BASE_REFCOUNTED_H_ 7 8 namespace base { 9 10 template <typename T> 11 class RefCounted { 12 public: 13 RefCounted() {} 14 protected: 15 ~RefCounted() {} 16 }; 17 18 template <typename T> 19 class RefCountedThreadSafe { 20 public: 21 RefCountedThreadSafe() {} 22 protected: 23 ~RefCountedThreadSafe() {} 24 }; 25 26 } // namespace base 27 28 // Ignore classes whose inheritance tree ends in WebKit's RefCounted base 29 // class. Though prone to error, this pattern is very prevalent in WebKit 30 // code, so do not issue any warnings. 31 namespace WebKit { 32 33 template <typename T> 34 class RefCounted { 35 public: 36 RefCounted() {} 37 ~RefCounted() {} 38 }; 39 40 } // namespace WebKit 41 42 // Unsafe; should error. 43 class PublicRefCountedDtorInHeader 44 : public base::RefCounted<PublicRefCountedDtorInHeader> { 45 public: 46 PublicRefCountedDtorInHeader() {} 47 ~PublicRefCountedDtorInHeader() {} 48 49 private: 50 friend class base::RefCounted<PublicRefCountedDtorInHeader>; 51 }; 52 53 // Unsafe; should error. 54 class PublicRefCountedThreadSafeDtorInHeader 55 : public base::RefCountedThreadSafe< 56 PublicRefCountedThreadSafeDtorInHeader> { 57 public: 58 PublicRefCountedThreadSafeDtorInHeader() {} 59 ~PublicRefCountedThreadSafeDtorInHeader() {} 60 61 private: 62 friend class base::RefCountedThreadSafe< 63 PublicRefCountedThreadSafeDtorInHeader>; 64 }; 65 66 // Unsafe; should error. 67 class ProtectedRefCountedDtorInHeader 68 : public base::RefCounted<ProtectedRefCountedDtorInHeader> { 69 public: 70 ProtectedRefCountedDtorInHeader() {} 71 72 protected: 73 ~ProtectedRefCountedDtorInHeader() {} 74 75 private: 76 friend class base::RefCounted<ProtectedRefCountedDtorInHeader>; 77 }; 78 79 // Safe; should not have errors 80 class ProtectedRefCountedVirtualDtorInHeader 81 : public base::RefCounted<ProtectedRefCountedVirtualDtorInHeader> { 82 public: 83 ProtectedRefCountedVirtualDtorInHeader() {} 84 85 protected: 86 virtual ~ProtectedRefCountedVirtualDtorInHeader() {} 87 88 private: 89 friend class base::RefCounted<ProtectedRefCountedVirtualDtorInHeader>; 90 }; 91 92 93 // Safe; should not have errors. 94 class PrivateRefCountedDtorInHeader 95 : public base::RefCounted<PrivateRefCountedDtorInHeader> { 96 public: 97 PrivateRefCountedDtorInHeader() {} 98 99 private: 100 ~PrivateRefCountedDtorInHeader() {} 101 friend class base::RefCounted<PrivateRefCountedDtorInHeader>; 102 }; 103 104 // Unsafe; A grandchild class ends up exposing their parent and grandparent's 105 // destructors. 106 class DerivedProtectedToPublicInHeader 107 : public ProtectedRefCountedVirtualDtorInHeader { 108 public: 109 DerivedProtectedToPublicInHeader() {} 110 virtual ~DerivedProtectedToPublicInHeader() {} 111 }; 112 113 // Unsafe; A grandchild ends up implicitly exposing their parent and 114 // grantparent's destructors. 115 class ImplicitDerivedProtectedToPublicInHeader 116 : public ProtectedRefCountedVirtualDtorInHeader { 117 public: 118 ImplicitDerivedProtectedToPublicInHeader() {} 119 }; 120 121 // Unsafe-but-ignored; should not have errors. 122 class WebKitPublicDtorInHeader 123 : public WebKit::RefCounted<WebKitPublicDtorInHeader> { 124 public: 125 WebKitPublicDtorInHeader() {} 126 ~WebKitPublicDtorInHeader() {} 127 }; 128 129 // Unsafe-but-ignored; should not have errors. 130 class WebKitDerivedPublicDtorInHeader 131 : public WebKitPublicDtorInHeader { 132 public: 133 WebKitDerivedPublicDtorInHeader() {} 134 ~WebKitDerivedPublicDtorInHeader() {} 135 }; 136 137 class APublicInterface { 138 public: 139 virtual ~APublicInterface() {} 140 virtual void DoFoo() = 0; 141 }; 142 143 // Unsafe. "ImplementsAPublicInterface* foo" can be deleted via 144 // "delete (APublicInterface*)foo;". 145 class ImplementsAPublicInterface 146 : public APublicInterface, 147 public base::RefCounted<ImplementsAPublicInterface> { 148 public: 149 virtual void DoFoo() override {} 150 151 protected: 152 virtual ~ImplementsAPublicInterface() {} 153 154 private: 155 friend class base::RefCounted<ImplementsAPublicInterface>; 156 }; 157 158 class AnImplicitInterface { 159 public: 160 virtual void DoBar() {} 161 }; 162 163 // Unsafe. 164 class ImplementsAnImplicitInterface 165 : public AnImplicitInterface, 166 public base::RefCounted<ImplementsAnImplicitInterface> { 167 public: 168 virtual void DoBar() override {} 169 170 private: 171 friend class base::RefCounted<ImplementsAnImplicitInterface>; 172 ~ImplementsAnImplicitInterface() {} 173 }; 174 175 // Safe. Private inheritance does not expose the base destructor. 176 class PrivatelyImplementsAPublicInterface 177 : private APublicInterface, 178 public base::RefCounted<PrivatelyImplementsAPublicInterface> { 179 public: 180 virtual void DoFoo() override {} 181 182 private: 183 friend class base::RefCounted<PrivatelyImplementsAPublicInterface>; 184 virtual ~PrivatelyImplementsAPublicInterface() {} 185 }; 186 187 // Unsafe. 188 class BaseInterface { 189 public: 190 virtual ~BaseInterface() {} 191 virtual void DoFoo() {} 192 }; 193 class DerivedInterface : public BaseInterface { 194 protected: 195 virtual ~DerivedInterface() {} 196 }; 197 class SomeOtherInterface { 198 public: 199 virtual ~SomeOtherInterface() {} 200 virtual void DoBar() {} 201 }; 202 class RefcountedType : public base::RefCounted<RefcountedType> { 203 protected: 204 ~RefcountedType() {} 205 private: 206 friend class base::RefCounted<RefcountedType>; 207 }; 208 class UnsafeInheritanceChain 209 : public DerivedInterface, 210 public SomeOtherInterface, 211 public RefcountedType { 212 public: 213 // DerivedInterface 214 virtual void DoFoo() override {} 215 216 // SomeOtherInterface 217 virtual void DoBar() override {} 218 219 protected: 220 virtual ~UnsafeInheritanceChain() {} 221 }; 222 223 #endif // BASE_REFCOUNTED_H_ 224