The leak detector is dead, long live asan and valgrind.

In resent times asan and valgrind have found way more memory management bugs
in llvm than the special purpose leak detector.

llvm-svn: 224703
This commit is contained in:
Rafael Espindola 2014-12-22 13:00:36 +00:00
parent 1e8df26ce8
commit dbf446fea1
13 changed files with 0 additions and 273 deletions

View File

@ -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

View 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);
}

View 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() {

View File

@ -27,7 +27,6 @@ add_llvm_library(LLVMCore
IntrinsicInst.cpp
LLVMContext.cpp
LLVMContextImpl.cpp
LeakDetector.cpp
LegacyPassManager.cpp
MDBuilder.cpp
Mangler.cpp

View 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

View 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() {

View 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;
}

View File

@ -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);
}

View 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);
}

View 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"

View 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() {

View File

@ -14,7 +14,6 @@ set(IRSources
DominatorTreeTest.cpp
IRBuilderTest.cpp
InstructionsTest.cpp
LeakDetectorTest.cpp
LegacyPassManagerTest.cpp
MDBuilderTest.cpp
MetadataTest.cpp

View File

@ -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
}