
Summary: This class is unnecessary. Its comment indicated that it was a compile error to allocate an instance of a class that inherits from RefCountedBaseVPTR on the stack. This may have been true at one point, but it's not today. Moreover you really do not want to allocate *any* refcounted object on the stack, vptrs or not, so if we did have a way to prevent these objects from being stack-allocated, we'd want to apply it to regular RefCountedBase too, obviating the need for a separate RefCountedBaseVPTR class. It seems that the main way RefCountedBaseVPTR provides safety is by making its subclass's destructor virtual. This may have been helpful at one point, but these days clang will emit an error if you define a class with virtual functions that inherits from RefCountedBase but doesn't have a virtual destructor. Reviewers: compnerd, dblaikie Subscribers: cfe-commits, klimek, llvm-commits, mgorny Differential Revision: https://reviews.llvm.org/D28162 llvm-svn: 290717
66 lines
1.9 KiB
C++
66 lines
1.9 KiB
C++
//===- unittest/ADT/IntrusiveRefCntPtrTest.cpp ----------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace llvm {
|
|
|
|
namespace {
|
|
struct SimpleRefCounted : public RefCountedBase<SimpleRefCounted> {
|
|
SimpleRefCounted() { ++NumInstances; }
|
|
SimpleRefCounted(const SimpleRefCounted &) { ++NumInstances; }
|
|
~SimpleRefCounted() { --NumInstances; }
|
|
|
|
static int NumInstances;
|
|
};
|
|
int SimpleRefCounted::NumInstances = 0;
|
|
} // anonymous namespace
|
|
|
|
TEST(IntrusiveRefCntPtr, RefCountedBaseCopyDoesNotLeak) {
|
|
EXPECT_EQ(0, SimpleRefCounted::NumInstances);
|
|
{
|
|
SimpleRefCounted *S1 = new SimpleRefCounted;
|
|
IntrusiveRefCntPtr<SimpleRefCounted> R1 = S1;
|
|
SimpleRefCounted *S2 = new SimpleRefCounted(*S1);
|
|
IntrusiveRefCntPtr<SimpleRefCounted> R2 = S2;
|
|
EXPECT_EQ(2, SimpleRefCounted::NumInstances);
|
|
}
|
|
EXPECT_EQ(0, SimpleRefCounted::NumInstances);
|
|
}
|
|
|
|
struct InterceptRefCounted : public RefCountedBase<InterceptRefCounted> {
|
|
InterceptRefCounted(bool *Released, bool *Retained)
|
|
: Released(Released), Retained(Retained) {}
|
|
bool * const Released;
|
|
bool * const Retained;
|
|
};
|
|
template <> struct IntrusiveRefCntPtrInfo<InterceptRefCounted> {
|
|
static void retain(InterceptRefCounted *I) {
|
|
*I->Retained = true;
|
|
I->Retain();
|
|
}
|
|
static void release(InterceptRefCounted *I) {
|
|
*I->Released = true;
|
|
I->Release();
|
|
}
|
|
};
|
|
TEST(IntrusiveRefCntPtr, UsesTraitsToRetainAndRelease) {
|
|
bool Released = false;
|
|
bool Retained = false;
|
|
{
|
|
InterceptRefCounted *I = new InterceptRefCounted(&Released, &Retained);
|
|
IntrusiveRefCntPtr<InterceptRefCounted> R = I;
|
|
}
|
|
EXPECT_TRUE(Released);
|
|
EXPECT_TRUE(Retained);
|
|
}
|
|
|
|
} // end namespace llvm
|