From d6790a9df811337f106cb98eabc53a63b9f8c24b Mon Sep 17 00:00:00 2001 From: Nathan James Date: Mon, 7 Dec 2020 20:20:08 +0000 Subject: [PATCH] [llvm] Add asserts in (ThreadSafe)?RefCountedBase destructors Added a trivial destructor in release mode and in debug mode a destructor that asserts RefCount is indeed zero. This ensure people aren't manually (maybe accidentally) destroying these objects like in this contrived example. ```lang=c++ { std::unique_ptr Object; holdIntrusiveOwnership(Object.get()); // Object Destructor called here will assert. } ``` Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D92480 --- include/llvm/ADT/IntrusiveRefCntPtr.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 41e5e6b9f8e..7e6585378ec 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -75,6 +75,18 @@ public: RefCountedBase(const RefCountedBase &) {} RefCountedBase &operator=(const RefCountedBase &) = delete; +#ifndef NDEBUG + ~RefCountedBase() { + assert(RefCount == 0 && + "Destruction occured when there are still references to this."); + } +#else + // Default the destructor in release builds, A trivial destructor may enable + // better codegen. + ~RefCountedBase() = default; +#endif + +public: void Retain() const { ++RefCount; } void Release() const { @@ -94,6 +106,17 @@ protected: ThreadSafeRefCountedBase & operator=(const ThreadSafeRefCountedBase &) = delete; +#ifndef NDEBUG + ~ThreadSafeRefCountedBase() { + assert(RefCount == 0 && + "Destruction occured when there are still references to this."); + } +#else + // Default the destructor in release builds, A trivial destructor may enable + // better codegen. + ~ThreadSafeRefCountedBase() = default; +#endif + public: void Retain() const { RefCount.fetch_add(1, std::memory_order_relaxed); }