OSDN Git Service

RefCountedBaseVPTR needs the IntrusiveRefCntPtrInfo as friend,
authorManuel Klimek <klimek@google.com>
Tue, 31 Jan 2012 19:58:34 +0000 (19:58 +0000)
committerManuel Klimek <klimek@google.com>
Tue, 31 Jan 2012 19:58:34 +0000 (19:58 +0000)
now that this handles the release / retain calls.

Adds a regression test for that bug (which is a compile-time
regression) and for the last two changes to the IntrusiveRefCntPtr,
especially tests for the memory leak due to copy construction of the
ref-counted object and ensuring that the traits are used for release /
retain calls.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149411 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/IntrusiveRefCntPtr.h
unittests/ADT/IntrusiveRefCntPtrTest.cpp [new file with mode: 0644]
unittests/CMakeLists.txt

index eae40c8..3a1a3f4 100644 (file)
@@ -80,7 +80,7 @@ namespace llvm {
     }
 
     template <typename T>
-    friend class IntrusiveRefCntPtr;
+    friend struct IntrusiveRefCntPtrInfo;
   };
 
   
diff --git a/unittests/ADT/IntrusiveRefCntPtrTest.cpp b/unittests/ADT/IntrusiveRefCntPtrTest.cpp
new file mode 100644 (file)
index 0000000..0c8c4ca
--- /dev/null
@@ -0,0 +1,64 @@
+//===- 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 {
+
+struct VirtualRefCounted : public RefCountedBaseVPTR {
+  virtual void f() {}
+};
+
+// Run this test with valgrind to detect memory leaks.
+TEST(IntrusiveRefCntPtr, RefCountedBaseVPTRCopyDoesNotLeak) {
+  VirtualRefCounted *V1 = new VirtualRefCounted;
+  IntrusiveRefCntPtr<VirtualRefCounted> R1 = V1;
+  VirtualRefCounted *V2 = new VirtualRefCounted(*V1);
+  IntrusiveRefCntPtr<VirtualRefCounted> R2 = V2;
+}
+
+struct SimpleRefCounted : public RefCountedBase<SimpleRefCounted> {};
+
+// Run this test with valgrind to detect memory leaks.
+TEST(IntrusiveRefCntPtr, RefCountedBaseCopyDoesNotLeak) {
+  SimpleRefCounted *S1 = new SimpleRefCounted;
+  IntrusiveRefCntPtr<SimpleRefCounted> R1 = S1;
+  SimpleRefCounted *S2 = new SimpleRefCounted(*S1);
+  IntrusiveRefCntPtr<SimpleRefCounted> R2 = S2;
+}
+
+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
index 6724f2d..977efd7 100644 (file)
@@ -64,6 +64,7 @@ add_llvm_unittest(ADT
   ADT/ImmutableSetTest.cpp
   ADT/IntEqClassesTest.cpp
   ADT/IntervalMapTest.cpp
+  ADT/IntrusiveRefCntPtrTest.cpp
   ADT/PackedVectorTest.cpp
   ADT/SmallBitVectorTest.cpp
   ADT/SmallStringTest.cpp