The leak detector is dead, long live asan and valgrind.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 22 Dec 2014 13:00:36 +0000 (13:00 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 22 Dec 2014 13:00:36 +0000 (13:00 +0000)
In resent times asan and valgrind have found way more memory management bugs
in llvm than the special purpose leak detector.

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

13 files changed:
include/llvm/IR/LeakDetector.h [deleted file]
lib/CodeGen/MachineBasicBlock.cpp
lib/IR/BasicBlock.cpp
lib/IR/CMakeLists.txt
lib/IR/Function.cpp
lib/IR/Globals.cpp
lib/IR/Instruction.cpp
lib/IR/LeakDetector.cpp [deleted file]
lib/IR/Metadata.cpp
lib/IR/Module.cpp
lib/IR/Value.cpp
unittests/IR/CMakeLists.txt
unittests/IR/LeakDetectorTest.cpp [deleted file]

diff --git a/include/llvm/IR/LeakDetector.h b/include/llvm/IR/LeakDetector.h
deleted file mode 100644 (file)
index b014fe0..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-//===- LeakDetector.h - Provide leak detection ------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a class that can be used to provide very simple memory leak
-// checks for an API.  Basically LLVM uses this to make sure that Instructions,
-// for example, are deleted when they are supposed to be, and not leaked away.
-//
-// When compiling with NDEBUG (Release build), this class does nothing, thus
-// adding no checking overhead to release builds.  Note that this class is
-// implemented in a very simple way, requiring completely manual manipulation
-// and checking for garbage, but this is intentional: users should not be using
-// this API, only other APIs should.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_LEAKDETECTOR_H
-#define LLVM_IR_LEAKDETECTOR_H
-
-#include <string>
-
-namespace llvm {
-
-class LLVMContext;
-class Value;
-class MDNode;
-
-struct LeakDetector {
-  /// addGarbageObject - Add a pointer to the internal set of "garbage" object
-  /// pointers.  This should be called when objects are created, or if they are
-  /// taken out of an owning collection.
-  ///
-  template <class T> static void addGarbageObject(T *Object) {
-#ifndef NDEBUG
-    addGarbageObjectImpl(Object);
-#endif
-  }
-
-  /// removeGarbageObject - Remove a pointer from our internal representation of
-  /// our "garbage" objects.  This should be called when an object is added to
-  /// an "owning" collection.
-  ///
-  template <class T> static void removeGarbageObject(T *Object) {
-#ifndef NDEBUG
-    removeGarbageObjectImpl(Object);
-#endif
-  }
-
-  /// checkForGarbage - Traverse the internal representation of garbage
-  /// pointers.  If there are any pointers that have been add'ed, but not
-  /// remove'd, big obnoxious warnings about memory leaks are issued.
-  ///
-  /// The specified message will be printed indicating when the check was
-  /// performed.
-  ///
-  static void checkForGarbage(LLVMContext &C, const std::string &Message) {
-#ifndef NDEBUG
-    checkForGarbageImpl(C, Message);
-#endif
-  }
-
-private:
-  /// Overload the normal methods to work better with Value* because they are
-  /// by far the most common in LLVM.
-  ///
-  /// Besides making the warning messages nicer, this hides errors by storing
-  /// Value* in a different leak-detection container than other classes.
-  static void addGarbageObjectImpl(const Value *Object);
-  static void removeGarbageObjectImpl(const Value *Object);
-
-  /// Overload the normal methods to work better with MDNode* to improve error
-  /// messages.
-  ///
-  /// For better or worse, this hides errors when other types are added as
-  /// garbage, deleted without being removed, and an MDNode is allocated in the
-  /// same spot.
-  ///
-  /// \note Only handle \a MDNode for now, since we can't always get access to
-  /// an \a LLVMContext for other \a Metadata types.
-  static void addGarbageObjectImpl(const MDNode *Object);
-  static void removeGarbageObjectImpl(const MDNode *Object);
-
-  static void addGarbageObjectImpl(void *Object);
-  static void removeGarbageObjectImpl(void *Object);
-  static void checkForGarbageImpl(LLVMContext &C, const std::string &Message);
-};
-
-} // End llvm namespace
-
-#endif
index a7dc1b328c1b34257daffe5a93bb14b20ed023e0..3c7390527e5fcd6d6cf45d62b4a86fda986b76d8 100644 (file)
@@ -24,7 +24,6 @@
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/DataLayout.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/Support/Debug.h"
@@ -45,7 +44,6 @@ MachineBasicBlock::MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb)
 }
 
 MachineBasicBlock::~MachineBasicBlock() {
-  LeakDetector::removeGarbageObject(this);
 }
 
 /// getSymbol - Return the MCSymbol for this basic block.
@@ -85,14 +83,11 @@ void ilist_traits<MachineBasicBlock>::addNodeToList(MachineBasicBlock *N) {
   for (MachineBasicBlock::instr_iterator
          I = N->instr_begin(), E = N->instr_end(); I != E; ++I)
     I->AddRegOperandsToUseLists(RegInfo);
-
-  LeakDetector::removeGarbageObject(N);
 }
 
 void ilist_traits<MachineBasicBlock>::removeNodeFromList(MachineBasicBlock *N) {
   N->getParent()->removeFromMBBNumbering(N->Number);
   N->Number = -1;
-  LeakDetector::addGarbageObject(N);
 }
 
 
index 5ed9bed1baff25ecb77fc838615692f88e899134..98a30621ff4b56a3b2514d000c9b954d433f57f4 100644 (file)
@@ -19,7 +19,6 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/IR/Type.h"
 #include <algorithm>
 using namespace llvm;
@@ -47,9 +46,6 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
                        BasicBlock *InsertBefore)
   : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr) {
 
-  // Make sure that we get added to a function
-  LeakDetector::addGarbageObject(this);
-
   if (NewParent)
     insertInto(NewParent, InsertBefore);
   else
@@ -94,14 +90,8 @@ BasicBlock::~BasicBlock() {
 }
 
 void BasicBlock::setParent(Function *parent) {
-  if (getParent())
-    LeakDetector::addGarbageObject(this);
-
   // Set Parent=parent, updating instruction symtab entries as appropriate.
   InstList.setSymTabObject(&Parent, parent);
-
-  if (getParent())
-    LeakDetector::removeGarbageObject(this);
 }
 
 void BasicBlock::removeFromParent() {
index 3b149e8690acb84f46cb8c1e48f24d8bb4b4cb62..1a210e05827546445c2a7607648f4f37f378214f 100644 (file)
@@ -27,7 +27,6 @@ add_llvm_library(LLVMCore
   IntrinsicInst.cpp
   LLVMContext.cpp
   LLVMContextImpl.cpp
-  LeakDetector.cpp
   LegacyPassManager.cpp
   MDBuilder.cpp
   Mangler.cpp
index ba6e4ce79a112d989f5734df43f68715469c9a9d..f462ec0890d8aa39fc44a00093a8f785132459f6 100644 (file)
@@ -23,7 +23,6 @@
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/RWMutex.h"
@@ -46,20 +45,13 @@ Argument::Argument(Type *Ty, const Twine &Name, Function *Par)
   : Value(Ty, Value::ArgumentVal) {
   Parent = nullptr;
 
-  // Make sure that we get added to a function
-  LeakDetector::addGarbageObject(this);
-
   if (Par)
     Par->getArgumentList().push_back(this);
   setName(Name);
 }
 
 void Argument::setParent(Function *parent) {
-  if (getParent())
-    LeakDetector::addGarbageObject(this);
   Parent = parent;
-  if (getParent())
-    LeakDetector::removeGarbageObject(this);
 }
 
 /// getArgNo - Return the index of this formal argument in its containing
@@ -260,9 +252,6 @@ Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name,
   if (Ty->getNumParams())
     setValueSubclassData(1);   // Set the "has lazy arguments" bit.
 
-  // Make sure that we get added to a function
-  LeakDetector::addGarbageObject(this);
-
   if (ParentModule)
     ParentModule->getFunctionList().push_back(this);
 
@@ -309,11 +298,7 @@ bool Function::arg_empty() const {
 }
 
 void Function::setParent(Module *parent) {
-  if (getParent())
-    LeakDetector::addGarbageObject(this);
   Parent = parent;
-  if (getParent())
-    LeakDetector::removeGarbageObject(this);
 }
 
 // dropAllReferences() - This function causes all the subinstructions to "let
index e181d623b858f2dc61caca57d706e2837ae7ae8b..54197d96763f049e071cdfe560e51137dd6b2e30 100644 (file)
@@ -18,7 +18,6 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -159,8 +158,6 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
            "Initializer should be the same type as the GlobalVariable!");
     Op<0>() = InitVal;
   }
-
-  LeakDetector::addGarbageObject(this);
 }
 
 GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
@@ -180,8 +177,6 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
     Op<0>() = InitVal;
   }
 
-  LeakDetector::addGarbageObject(this);
-
   if (Before)
     Before->getParent()->getGlobalList().insert(Before, this);
   else
@@ -189,11 +184,7 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
 }
 
 void GlobalVariable::setParent(Module *parent) {
-  if (getParent())
-    LeakDetector::addGarbageObject(this);
   Parent = parent;
-  if (getParent())
-    LeakDetector::removeGarbageObject(this);
 }
 
 void GlobalVariable::removeFromParent() {
@@ -259,7 +250,6 @@ GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
                          Module *ParentModule)
     : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalAliasVal,
                   &Op<0>(), 1, Link, Name) {
-  LeakDetector::addGarbageObject(this);
   Op<0>() = Aliasee;
 
   if (ParentModule)
@@ -296,11 +286,7 @@ GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) {
 }
 
 void GlobalAlias::setParent(Module *parent) {
-  if (getParent())
-    LeakDetector::addGarbageObject(this);
   Parent = parent;
-  if (getParent())
-    LeakDetector::removeGarbageObject(this);
 }
 
 void GlobalAlias::removeFromParent() {
index 3ee66f56981072271fc85cc83a3d4d7ad68ace66..92c6e9f3dede0f475270dc8a0dbe418b9732b8c3 100644 (file)
@@ -15,7 +15,6 @@
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Instructions.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/Type.h"
@@ -24,8 +23,6 @@ using namespace llvm;
 Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
                          Instruction *InsertBefore)
   : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
-  // Make sure that we get added to a basicblock
-  LeakDetector::addGarbageObject(this);
 
   // If requested, insert this instruction into a basic block...
   if (InsertBefore) {
@@ -42,8 +39,6 @@ const DataLayout *Instruction::getDataLayout() const {
 Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
                          BasicBlock *InsertAtEnd)
   : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
-  // Make sure that we get added to a basicblock
-  LeakDetector::addGarbageObject(this);
 
   // append this instruction into the basic block
   assert(InsertAtEnd && "Basic block to append to may not be NULL!");
@@ -60,12 +55,6 @@ Instruction::~Instruction() {
 
 
 void Instruction::setParent(BasicBlock *P) {
-  if (getParent()) {
-    if (!P) LeakDetector::addGarbageObject(this);
-  } else {
-    if (P) LeakDetector::removeGarbageObject(this);
-  }
-
   Parent = P;
 }
 
diff --git a/lib/IR/LeakDetector.cpp b/lib/IR/LeakDetector.cpp
deleted file mode 100644 (file)
index be07a48..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the LeakDetector class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/LeakDetector.h"
-#include "LLVMContextImpl.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Value.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Mutex.h"
-#include "llvm/Support/Threading.h"
-using namespace llvm;
-
-static ManagedStatic<sys::SmartMutex<true> > ObjectsLock;
-static ManagedStatic<LeakDetectorImpl<void> > Objects;
-
-static void clearGarbage(LLVMContext &Context) {
-  Objects->clear();
-  Context.pImpl->LLVMObjects.clear();
-}
-
-void LeakDetector::addGarbageObjectImpl(void *Object) {
-  sys::SmartScopedLock<true> Lock(*ObjectsLock);
-  Objects->addGarbage(Object);
-}
-
-void LeakDetector::addGarbageObjectImpl(const Value *Object) {
-  LLVMContextImpl *pImpl = Object->getContext().pImpl;
-  pImpl->LLVMObjects.addGarbage(Object);
-}
-
-void LeakDetector::addGarbageObjectImpl(const MDNode *Object) {
-  LLVMContextImpl *pImpl = Object->getContext().pImpl;
-  pImpl->LLVMMDObjects.addGarbage(Object);
-}
-
-void LeakDetector::removeGarbageObjectImpl(void *Object) {
-  sys::SmartScopedLock<true> Lock(*ObjectsLock);
-  Objects->removeGarbage(Object);
-}
-
-void LeakDetector::removeGarbageObjectImpl(const Value *Object) {
-  LLVMContextImpl *pImpl = Object->getContext().pImpl;
-  pImpl->LLVMObjects.removeGarbage(Object);
-}
-
-void LeakDetector::removeGarbageObjectImpl(const MDNode *Object) {
-  LLVMContextImpl *pImpl = Object->getContext().pImpl;
-  pImpl->LLVMMDObjects.removeGarbage(Object);
-}
-
-void LeakDetector::checkForGarbageImpl(LLVMContext &Context, 
-                                       const std::string &Message) {
-  LLVMContextImpl *pImpl = Context.pImpl;
-  sys::SmartScopedLock<true> Lock(*ObjectsLock);
-  
-  Objects->setName("GENERIC");
-  pImpl->LLVMObjects.setName("LLVM");
-  pImpl->LLVMMDObjects.setName("LLVM-MD");
-  
-  // use non-short-circuit version so that both checks are performed
-  if (Objects->hasGarbage(Message) |
-      pImpl->LLVMObjects.hasGarbage(Message) |
-      pImpl->LLVMMDObjects.hasGarbage(Message))
-    errs() << "\nThis is probably because you removed an object, but didn't "
-           << "delete it.  Please check your code for memory leaks.\n";
-
-  // Clear out results so we don't get duplicate warnings on
-  // next call...
-  clearGarbage(Context);
-}
index 936c129662dbeafddc50ddafb9d789d3b08275f1..4b099ec255f3f60fc5882eb9db554f800adb6a43 100644 (file)
@@ -22,7 +22,6 @@
 #include "llvm/IR/ConstantRange.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ValueHandle.h"
 
@@ -596,13 +595,11 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,
 MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context,
                                     ArrayRef<Metadata *> MDs) {
   MDNodeFwdDecl *N = new (MDs.size()) MDNodeFwdDecl(Context, MDs);
-  LeakDetector::addGarbageObject(N);
   return N;
 }
 
 void MDNode::deleteTemporary(MDNode *N) {
   assert(isa<MDNodeFwdDecl>(N) && "Expected forward declaration");
-  LeakDetector::removeGarbageObject(N);
   delete cast<MDNodeFwdDecl>(N);
 }
 
index 71640bfb9f37344bc87b44b0d87c19d1dd41ae89..d32ffcdac33704f8f5ae622b6a1721d63a2b0dc4 100644 (file)
@@ -22,7 +22,6 @@
 #include "llvm/IR/GVMaterializer.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/IR/TypeFinder.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/Path.h"
index d790f9e10898bad1527304e8208ca62d15655af7..a9e6a72f0acd12dbfa597702584ecccde940ec86 100644 (file)
@@ -23,7 +23,6 @@
 #include "llvm/IR/GetElementPtrTypeIterator.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instructions.h"
-#include "llvm/IR/LeakDetector.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/ValueHandle.h"
@@ -84,9 +83,6 @@ Value::~Value() {
   // If this value is named, destroy the name.  This should not be in a symtab
   // at this point.
   destroyValueName();
-
-  // There should be no uses of this object anymore, remove it.
-  LeakDetector::removeGarbageObject(this);
 }
 
 void Value::destroyValueName() {
index a0462091a3140d041db4d4af461fd2298116f030..0c2979632e10762cdb2a78038a37d1ebba18bb13 100644 (file)
@@ -14,7 +14,6 @@ set(IRSources
   DominatorTreeTest.cpp
   IRBuilderTest.cpp
   InstructionsTest.cpp
-  LeakDetectorTest.cpp
   LegacyPassManagerTest.cpp
   MDBuilderTest.cpp
   MetadataTest.cpp
diff --git a/unittests/IR/LeakDetectorTest.cpp b/unittests/IR/LeakDetectorTest.cpp
deleted file mode 100644 (file)
index 94eed4c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-//===- LeakDetectorTest.cpp -----------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/LeakDetector.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-namespace {
-
-#ifdef GTEST_HAS_DEATH_TEST
-#ifndef NDEBUG
-TEST(LeakDetector, Death1) {
-  LeakDetector::addGarbageObject((void*) 1);
-  LeakDetector::addGarbageObject((void*) 2);
-
-  EXPECT_DEATH(LeakDetector::addGarbageObject((void*) 1),
-               ".*Ts.count\\(o\\) == 0 && \"Object already in set!\"");
-  EXPECT_DEATH(LeakDetector::addGarbageObject((void*) 2),
-               "Cache != o && \"Object already in set!\"");
-}
-#endif
-#endif
-
-}