| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BASE_REFCOUNTED_H_ |
| #define BASE_REFCOUNTED_H_ |
| |
| namespace base { |
| |
| template <typename T> |
| class RefCounted { |
| public: |
| RefCounted() {} |
| protected: |
| ~RefCounted() {} |
| }; |
| |
| template <typename T> |
| class RefCountedThreadSafe { |
| public: |
| RefCountedThreadSafe() {} |
| protected: |
| ~RefCountedThreadSafe() {} |
| }; |
| |
| } // namespace base |
| |
| // Ignore classes whose inheritance tree ends in WebKit's RefCounted base |
| // class. Though prone to error, this pattern is very prevalent in WebKit |
| // code, so do not issue any warnings. |
| namespace WebKit { |
| |
| template <typename T> |
| class RefCounted { |
| public: |
| RefCounted() {} |
| ~RefCounted() {} |
| }; |
| |
| } // namespace WebKit |
| |
| // Unsafe; should error. |
| class PublicRefCountedDtorInHeader |
| : public base::RefCounted<PublicRefCountedDtorInHeader> { |
| public: |
| PublicRefCountedDtorInHeader() {} |
| ~PublicRefCountedDtorInHeader() {} |
| |
| private: |
| friend class base::RefCounted<PublicRefCountedDtorInHeader>; |
| }; |
| |
| // Unsafe; should error. |
| class PublicRefCountedThreadSafeDtorInHeader |
| : public base::RefCountedThreadSafe< |
| PublicRefCountedThreadSafeDtorInHeader> { |
| public: |
| PublicRefCountedThreadSafeDtorInHeader() {} |
| ~PublicRefCountedThreadSafeDtorInHeader() {} |
| |
| private: |
| friend class base::RefCountedThreadSafe< |
| PublicRefCountedThreadSafeDtorInHeader>; |
| }; |
| |
| // Unsafe; should error. |
| class ProtectedRefCountedDtorInHeader |
| : public base::RefCounted<ProtectedRefCountedDtorInHeader> { |
| public: |
| ProtectedRefCountedDtorInHeader() {} |
| |
| protected: |
| ~ProtectedRefCountedDtorInHeader() {} |
| |
| private: |
| friend class base::RefCounted<ProtectedRefCountedDtorInHeader>; |
| }; |
| |
| // Safe; should not have errors |
| class ProtectedRefCountedVirtualDtorInHeader |
| : public base::RefCounted<ProtectedRefCountedVirtualDtorInHeader> { |
| public: |
| ProtectedRefCountedVirtualDtorInHeader() {} |
| |
| protected: |
| virtual ~ProtectedRefCountedVirtualDtorInHeader() {} |
| |
| private: |
| friend class base::RefCounted<ProtectedRefCountedVirtualDtorInHeader>; |
| }; |
| |
| |
| // Safe; should not have errors. |
| class PrivateRefCountedDtorInHeader |
| : public base::RefCounted<PrivateRefCountedDtorInHeader> { |
| public: |
| PrivateRefCountedDtorInHeader() {} |
| |
| private: |
| ~PrivateRefCountedDtorInHeader() {} |
| friend class base::RefCounted<PrivateRefCountedDtorInHeader>; |
| }; |
| |
| // Unsafe; A grandchild class ends up exposing their parent and grandparent's |
| // destructors. |
| class DerivedProtectedToPublicInHeader |
| : public ProtectedRefCountedVirtualDtorInHeader { |
| public: |
| DerivedProtectedToPublicInHeader() {} |
| ~DerivedProtectedToPublicInHeader() override {} |
| }; |
| |
| // Unsafe; A grandchild ends up implicitly exposing their parent and |
| // grantparent's destructors. |
| class ImplicitDerivedProtectedToPublicInHeader |
| : public ProtectedRefCountedVirtualDtorInHeader { |
| public: |
| ImplicitDerivedProtectedToPublicInHeader() {} |
| }; |
| |
| // Unsafe-but-ignored; should not have errors. |
| class WebKitPublicDtorInHeader |
| : public WebKit::RefCounted<WebKitPublicDtorInHeader> { |
| public: |
| WebKitPublicDtorInHeader() {} |
| ~WebKitPublicDtorInHeader() {} |
| }; |
| |
| // Unsafe-but-ignored; should not have errors. |
| class WebKitDerivedPublicDtorInHeader |
| : public WebKitPublicDtorInHeader { |
| public: |
| WebKitDerivedPublicDtorInHeader() {} |
| ~WebKitDerivedPublicDtorInHeader() {} |
| }; |
| |
| class APublicInterface { |
| public: |
| virtual ~APublicInterface() {} |
| virtual void DoFoo() = 0; |
| }; |
| |
| // Unsafe. "ImplementsAPublicInterface* foo" can be deleted via |
| // "delete (APublicInterface*)foo;". |
| class ImplementsAPublicInterface |
| : public APublicInterface, |
| public base::RefCounted<ImplementsAPublicInterface> { |
| public: |
| void DoFoo() override {} |
| |
| protected: |
| ~ImplementsAPublicInterface() override {} |
| |
| private: |
| friend class base::RefCounted<ImplementsAPublicInterface>; |
| }; |
| |
| class AnImplicitInterface { |
| public: |
| virtual void DoBar() {} |
| }; |
| |
| // Unsafe. |
| class ImplementsAnImplicitInterface |
| : public AnImplicitInterface, |
| public base::RefCounted<ImplementsAnImplicitInterface> { |
| public: |
| void DoBar() override {} |
| |
| private: |
| friend class base::RefCounted<ImplementsAnImplicitInterface>; |
| ~ImplementsAnImplicitInterface() {} |
| }; |
| |
| // Safe. Private inheritance does not expose the base destructor. |
| class PrivatelyImplementsAPublicInterface |
| : private APublicInterface, |
| public base::RefCounted<PrivatelyImplementsAPublicInterface> { |
| public: |
| void DoFoo() override {} |
| |
| private: |
| friend class base::RefCounted<PrivatelyImplementsAPublicInterface>; |
| ~PrivatelyImplementsAPublicInterface() override {} |
| }; |
| |
| // Unsafe. |
| class BaseInterface { |
| public: |
| virtual ~BaseInterface() {} |
| virtual void DoFoo() {} |
| }; |
| class DerivedInterface : public BaseInterface { |
| protected: |
| ~DerivedInterface() override {} |
| }; |
| class SomeOtherInterface { |
| public: |
| virtual ~SomeOtherInterface() {} |
| virtual void DoBar() {} |
| }; |
| class RefcountedType : public base::RefCounted<RefcountedType> { |
| protected: |
| ~RefcountedType() {} |
| private: |
| friend class base::RefCounted<RefcountedType>; |
| }; |
| class UnsafeInheritanceChain |
| : public DerivedInterface, |
| public SomeOtherInterface, |
| public RefcountedType { |
| public: |
| // DerivedInterface |
| void DoFoo() override {} |
| |
| // SomeOtherInterface |
| void DoBar() override {} |
| |
| protected: |
| ~UnsafeInheritanceChain() override {} |
| }; |
| |
| #endif // BASE_REFCOUNTED_H_ |