Home | History | Annotate | Download | only in tests
      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