• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
RefCounted()13   RefCounted() {}
14  protected:
~RefCounted()15   ~RefCounted() {}
16 };
17 
18 template <typename T>
19 class RefCountedThreadSafe {
20  public:
RefCountedThreadSafe()21   RefCountedThreadSafe() {}
22  protected:
~RefCountedThreadSafe()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:
RefCounted()36   RefCounted() {}
~RefCounted()37   ~RefCounted() {}
38 };
39 
40 }  // namespace WebKit
41 
42 // Unsafe; should error.
43 class PublicRefCountedDtorInHeader
44     : public base::RefCounted<PublicRefCountedDtorInHeader> {
45  public:
PublicRefCountedDtorInHeader()46   PublicRefCountedDtorInHeader() {}
~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:
PublicRefCountedThreadSafeDtorInHeader()58   PublicRefCountedThreadSafeDtorInHeader() {}
~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:
ProtectedRefCountedDtorInHeader()70   ProtectedRefCountedDtorInHeader() {}
71 
72  protected:
~ProtectedRefCountedDtorInHeader()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:
ProtectedRefCountedVirtualDtorInHeader()83   ProtectedRefCountedVirtualDtorInHeader() {}
84 
85  protected:
~ProtectedRefCountedVirtualDtorInHeader()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:
PrivateRefCountedDtorInHeader()97   PrivateRefCountedDtorInHeader() {}
98 
99  private:
~PrivateRefCountedDtorInHeader()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:
DerivedProtectedToPublicInHeader()109   DerivedProtectedToPublicInHeader() {}
~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:
ImplicitDerivedProtectedToPublicInHeader()118   ImplicitDerivedProtectedToPublicInHeader() {}
119 };
120 
121 // Unsafe-but-ignored; should not have errors.
122 class WebKitPublicDtorInHeader
123     : public WebKit::RefCounted<WebKitPublicDtorInHeader> {
124  public:
WebKitPublicDtorInHeader()125   WebKitPublicDtorInHeader() {}
~WebKitPublicDtorInHeader()126   ~WebKitPublicDtorInHeader() {}
127 };
128 
129 // Unsafe-but-ignored; should not have errors.
130 class WebKitDerivedPublicDtorInHeader
131     : public WebKitPublicDtorInHeader {
132  public:
WebKitDerivedPublicDtorInHeader()133   WebKitDerivedPublicDtorInHeader() {}
~WebKitDerivedPublicDtorInHeader()134   ~WebKitDerivedPublicDtorInHeader() {}
135 };
136 
137 class APublicInterface {
138  public:
~APublicInterface()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:
DoFoo()149   virtual void DoFoo() override {}
150 
151  protected:
~ImplementsAPublicInterface()152   virtual ~ImplementsAPublicInterface() {}
153 
154  private:
155   friend class base::RefCounted<ImplementsAPublicInterface>;
156 };
157 
158 class AnImplicitInterface {
159  public:
DoBar()160   virtual void DoBar() {}
161 };
162 
163 // Unsafe.
164 class ImplementsAnImplicitInterface
165     : public AnImplicitInterface,
166       public base::RefCounted<ImplementsAnImplicitInterface> {
167  public:
DoBar()168   virtual void DoBar() override {}
169 
170  private:
171   friend class base::RefCounted<ImplementsAnImplicitInterface>;
~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:
DoFoo()180   virtual void DoFoo() override {}
181 
182  private:
183   friend class base::RefCounted<PrivatelyImplementsAPublicInterface>;
~PrivatelyImplementsAPublicInterface()184   virtual ~PrivatelyImplementsAPublicInterface() {}
185 };
186 
187 // Unsafe.
188 class BaseInterface {
189  public:
~BaseInterface()190   virtual ~BaseInterface() {}
DoFoo()191   virtual void DoFoo() {}
192 };
193 class DerivedInterface : public BaseInterface {
194  protected:
~DerivedInterface()195   virtual ~DerivedInterface() {}
196 };
197 class SomeOtherInterface {
198  public:
~SomeOtherInterface()199   virtual ~SomeOtherInterface() {}
DoBar()200   virtual void DoBar() {}
201 };
202 class RefcountedType : public base::RefCounted<RefcountedType> {
203  protected:
~RefcountedType()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
DoFoo()214   virtual void DoFoo() override {}
215 
216   // SomeOtherInterface
DoBar()217   virtual void DoBar() override {}
218 
219  protected:
~UnsafeInheritanceChain()220   virtual ~UnsafeInheritanceChain() {}
221 };
222 
223 #endif  // BASE_REFCOUNTED_H_
224