From de69a4ca2fd66cc600116a10bef1f3ab1610d62c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 8 Sep 2002 18:51:16 +0000 Subject: [PATCH] Checkin initial support for automatic memory leak detection routines git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3618 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/LeakDetector.cpp | 66 ++++++++++++++++++++++++++++ lib/VMCore/LeakDetector.cpp | 66 ++++++++++++++++++++++++++++ support/lib/Support/LeakDetector.cpp | 66 ++++++++++++++++++++++++++++ 3 files changed, 198 insertions(+) create mode 100644 lib/Support/LeakDetector.cpp create mode 100644 lib/VMCore/LeakDetector.cpp create mode 100644 support/lib/Support/LeakDetector.cpp diff --git a/lib/Support/LeakDetector.cpp b/lib/Support/LeakDetector.cpp new file mode 100644 index 00000000000..0d7b4bedf3d --- /dev/null +++ b/lib/Support/LeakDetector.cpp @@ -0,0 +1,66 @@ +//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===// +// +// This file implements the LeakDetector class. +// +//===----------------------------------------------------------------------===// + +#include "Support/LeakDetector.h" +#include "llvm/Value.h" +#include +#include + +// Lazily allocate set so that release build doesn't have to do anything. +static std::set *Objects = 0; +static std::set *LLVMObjects = 0; + +void LeakDetector::addGarbageObjectImpl(void *Object) { + if (Objects == 0) + Objects = new std::set(); + assert(Objects->count(Object) == 0 && "Object already in set!"); + Objects->insert(Object); +} + +void LeakDetector::removeGarbageObjectImpl(void *Object) { + if (Objects) + Objects->erase(Object); +} + +void LeakDetector::addGarbageObjectImpl(const Value *Object) { + if (LLVMObjects == 0) + LLVMObjects = new std::set(); + assert(LLVMObjects->count(Object) == 0 && "Object already in set!"); + LLVMObjects->insert(Object); +} + +void LeakDetector::removeGarbageObjectImpl(const Value *Object) { + if (LLVMObjects) + LLVMObjects->erase(Object); +} + +void LeakDetector::checkForGarbageImpl(const std::string &Message) { + if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){ + std::cerr << "Leaked objects found: " << Message << "\n"; + + if (Objects && !Objects->empty()) { + std::cerr << " Non-Value objects leaked:"; + for (std::set::iterator I = Objects->begin(), + E = Objects->end(); I != E; ++I) + std::cerr << " " << *I; + } + + if (LLVMObjects && !LLVMObjects->empty()) { + std::cerr << " LLVM Value subclasses leaked:"; + for (std::set::iterator I = LLVMObjects->begin(), + E = LLVMObjects->end(); I != E; ++I) + std::cerr << **I << "\n"; + } + + std::cerr << "This is probably because you removed an LLVM value " + << "(Instruction, BasicBlock, \netc), 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... + delete Objects; delete LLVMObjects; + Objects = 0; LLVMObjects = 0; + } +} diff --git a/lib/VMCore/LeakDetector.cpp b/lib/VMCore/LeakDetector.cpp new file mode 100644 index 00000000000..0d7b4bedf3d --- /dev/null +++ b/lib/VMCore/LeakDetector.cpp @@ -0,0 +1,66 @@ +//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===// +// +// This file implements the LeakDetector class. +// +//===----------------------------------------------------------------------===// + +#include "Support/LeakDetector.h" +#include "llvm/Value.h" +#include +#include + +// Lazily allocate set so that release build doesn't have to do anything. +static std::set *Objects = 0; +static std::set *LLVMObjects = 0; + +void LeakDetector::addGarbageObjectImpl(void *Object) { + if (Objects == 0) + Objects = new std::set(); + assert(Objects->count(Object) == 0 && "Object already in set!"); + Objects->insert(Object); +} + +void LeakDetector::removeGarbageObjectImpl(void *Object) { + if (Objects) + Objects->erase(Object); +} + +void LeakDetector::addGarbageObjectImpl(const Value *Object) { + if (LLVMObjects == 0) + LLVMObjects = new std::set(); + assert(LLVMObjects->count(Object) == 0 && "Object already in set!"); + LLVMObjects->insert(Object); +} + +void LeakDetector::removeGarbageObjectImpl(const Value *Object) { + if (LLVMObjects) + LLVMObjects->erase(Object); +} + +void LeakDetector::checkForGarbageImpl(const std::string &Message) { + if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){ + std::cerr << "Leaked objects found: " << Message << "\n"; + + if (Objects && !Objects->empty()) { + std::cerr << " Non-Value objects leaked:"; + for (std::set::iterator I = Objects->begin(), + E = Objects->end(); I != E; ++I) + std::cerr << " " << *I; + } + + if (LLVMObjects && !LLVMObjects->empty()) { + std::cerr << " LLVM Value subclasses leaked:"; + for (std::set::iterator I = LLVMObjects->begin(), + E = LLVMObjects->end(); I != E; ++I) + std::cerr << **I << "\n"; + } + + std::cerr << "This is probably because you removed an LLVM value " + << "(Instruction, BasicBlock, \netc), 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... + delete Objects; delete LLVMObjects; + Objects = 0; LLVMObjects = 0; + } +} diff --git a/support/lib/Support/LeakDetector.cpp b/support/lib/Support/LeakDetector.cpp new file mode 100644 index 00000000000..0d7b4bedf3d --- /dev/null +++ b/support/lib/Support/LeakDetector.cpp @@ -0,0 +1,66 @@ +//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===// +// +// This file implements the LeakDetector class. +// +//===----------------------------------------------------------------------===// + +#include "Support/LeakDetector.h" +#include "llvm/Value.h" +#include +#include + +// Lazily allocate set so that release build doesn't have to do anything. +static std::set *Objects = 0; +static std::set *LLVMObjects = 0; + +void LeakDetector::addGarbageObjectImpl(void *Object) { + if (Objects == 0) + Objects = new std::set(); + assert(Objects->count(Object) == 0 && "Object already in set!"); + Objects->insert(Object); +} + +void LeakDetector::removeGarbageObjectImpl(void *Object) { + if (Objects) + Objects->erase(Object); +} + +void LeakDetector::addGarbageObjectImpl(const Value *Object) { + if (LLVMObjects == 0) + LLVMObjects = new std::set(); + assert(LLVMObjects->count(Object) == 0 && "Object already in set!"); + LLVMObjects->insert(Object); +} + +void LeakDetector::removeGarbageObjectImpl(const Value *Object) { + if (LLVMObjects) + LLVMObjects->erase(Object); +} + +void LeakDetector::checkForGarbageImpl(const std::string &Message) { + if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){ + std::cerr << "Leaked objects found: " << Message << "\n"; + + if (Objects && !Objects->empty()) { + std::cerr << " Non-Value objects leaked:"; + for (std::set::iterator I = Objects->begin(), + E = Objects->end(); I != E; ++I) + std::cerr << " " << *I; + } + + if (LLVMObjects && !LLVMObjects->empty()) { + std::cerr << " LLVM Value subclasses leaked:"; + for (std::set::iterator I = LLVMObjects->begin(), + E = LLVMObjects->end(); I != E; ++I) + std::cerr << **I << "\n"; + } + + std::cerr << "This is probably because you removed an LLVM value " + << "(Instruction, BasicBlock, \netc), 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... + delete Objects; delete LLVMObjects; + Objects = 0; LLVMObjects = 0; + } +}