[LLVMdev] New type of smart pointer for LLVM
Anton Yartsev
anton.yartsev at gmail.com
Wed Sep 24 19:12:30 PDT 2014
Hello everyone,
I bring to discussion the necessity/design of a new type of smart
pointer. r215176 and r217791 rise the problem, D5443
<http://reviews.llvm.org/D5443> is devoted to the solution.
r215176 applies several temporary ugly fixes of memory leaks in
TGParser.cpp which would be great to be refactored using smart pointers.
D5443 <http://reviews.llvm.org/D5443> demonstrates how the solution with
a certain type of smart pointer would look like (see changes in
TGParser::ParseDef(), TGParser::InstantiateMulticlassDef() and
TGParser::ParseSimpleValue()).
Briefly:
consider a leaky example:
{
T* p = new T;
if (condition1) {
f(p); // takes ownership of p
}
p->SomeMethod();
if (condition2) {
return nullptr; // Leak!
}
g(p); // don't take ownership of p
return p;
}
The preferred solution would look like:
{
smart_ptr<T> p(new T);
if (condition1) {
f(p.StopOwn()); // takes ownership of p
}
p->SomeMethod();
if (condition2) {
return nullptr; //
}
g(p.Get()); // don't take ownership of p
return p.StopOwn();
}
Neither unique_ptr nor shared_ptr can be used in the place of smart_ptr
as unique_ptr sets the raw pointer to nullptr after release() (StopOwn()
in the example above) whereas shared_ptr is unable to release.
Attached is a scratch that illustrates how the minimal
API/implementation of a desired smart pointer sufficient for refactoring
would look like. Any ideas and suggestions are appreciated.
--
Anton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140925/fb27d622/attachment.html>
-------------- next part --------------
//===-- CondOwnershipPtr.h - Smart ptr with conditional release -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_CONDOWNERSHIPPTR_H
#define LLVM_ADT_CONDOWNERSHIPPTR_H
namespace llvm {
template<class T>
class CondOwnershipPtr {
T* Ptr;
bool Own;
void Delete() {
if (Ptr && !Own)
delete Ptr;
}
public:
CondOwnershipPtr() : Ptr(nullptr), Own(true) {}
explicit CondOwnershipPtr(T* p) : Ptr(p), Own(true) {}
~CondOwnershipPtr() {
Delete();
}
T* Get() const {
return Ptr;
}
T* StopOwn() const {
Own = false;
return Ptr;
}
void Reset(T* P = nullptr) {
if (P != Ptr) {
Delete();
Ptr = P;
Own = true;
}
}
bool Owns() const {
return Own;
}
operator bool() const {
return Ptr != nullptr;
}
T& operator*() const {
return *Ptr;
}
T* operator->() const {
return Ptr;
}
};
} // end namespace llvm
#endif
More information about the llvm-dev
mailing list